How to configure Spock test to load Spring Context (for @Autowired)?

11k views Asked by At

I have such Application class:

@Configuration
@EnableAutoConfiguration
@ComponentScan
@ImportResource("classpath:applicationContext.xml")
@EnableJpaRepositories("ibd.jpa")
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}
}

I also have this UserService class (it is discovered by @EnableJpaRepositories("ibd.jpa")):

@RestController
@RequestMapping("/user")
public class UserService {

@Autowired
private UserRepository userRepository;

@RequestMapping(method = RequestMethod.POST)
public User createUser(@RequestParam String login, @RequestParam String password){
    return userRepository.save(new User(login,password));
} 

And I try to test in this UserService:

@ContextConfiguration
class UserServiceTest extends Specification {

@Autowired
def UserService userService


def "if User not exists 404 status in response sent and corresponding message shown"() {
    when: 'rest account url is hit'
    MockMvc mockMvc = standaloneSetup(userService).build()
        def response = mockMvc.perform(get('/user?login=wrongusername&password=wrongPassword')).andReturn().response
    then:
        response.status == NOT_FOUND.value()
        response.errorMessage == "Login or password is not correct"

}

But the issue is: UserService in test is null - it doesn't get successfully @Autowired; that shows that the Spring Context didn't load. How can I configure for successful Autowiring?

2

There are 2 answers

0
Lesya Makhova On BEST ANSWER

Was solved by:

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = Application.class)
@WebAppConfiguration
@IntegrationTest

and usage of RestTemplate

as in this question

2
Igor On

Expanding on this since the bounty wanted some elaboration: Spring doesn't wire up beans by default in unit tests. That's why those annotations are needed. I'll try to break them down a little bit:

  • Uses SpringBootContextLoader as the default ContextLoader when no specific @ContextConfiguration(loader=...) is defined.
  • Automatically searches for a @SpringBootConfiguration when nested @Configuration is not used, and no explicit classes are specified.

Without these annotations, Spring doesn't wire up the beans necessary for your test configuration. This is partially for performance reasons (most tests don't need the context configured).