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

2

9

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?

Storey answered 15/6, 2015 at 9:33 Comment(1)
Possible duplicate of prior #24406227Penguin
S
6

Was solved by:

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

and usage of RestTemplate

as in this question

Storey answered 15/6, 2015 at 10:48 Comment(0)
A
6

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).

Allison answered 5/10, 2017 at 14:58 Comment(2)
could you please add some notes about using Spring (not SpringBoot)?Ustulation
@ДмитрийКулешов The latter two annotations are not specific to Spring Boot. I think the first one could be replaced with something like "@RunWith" but I'm not sure as I've only ever used these with Spring Boot. What are you specifically trying to do?Allison

© 2022 - 2024 — McMap. All rights reserved.