Reputation: 5867
I have a GreetingController
@Controller
public class GreetingController {
@RequestMapping("/greeting")
public @ResponseBody String greeting() {
return "Hello, same to you";
}
}
and GreetingControllerTest
@WebMvcTest(GreetingController.class)
public class WebMockTest {
@Autowired
private MockMvc mockMvc;
@Test
public void greetingShouldReturnMessageFromService() throws Exception {
this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString("Hello, same to you")));
}
}
I am running the test in intelliJ hoping that it will not load the application context, but it starts with launching the application.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.5.RELEASE)
{"thread":"main","level":"INFO","loggerName":..........
As per spring doc we can narrow the tests to only the web layer by using @WebMvcTest.
Does this mean that it still loads the application context? Or maybe I did not understand it correctly.
Upvotes: 2
Views: 3474
Reputation: 156
I had the same problem where the test bootup the WHOLE CONTEXT(i KNOW it because it tried to load all my @Repository code), and i found a workaround for this, it's very nasty:
@ContextConfiguration(classes ={Controller.TestConfig.class})
@WebMvcTest(Controller.class)
class ControllerTest {
@Configuration
public static class TestConfig {
@Bean
public Controller controller() {
return new Controller();
}
}
I know substituting the actual Spring context with a test one is kind of a makeshift solution, but i cant think of anything else.
Upvotes: 0
Reputation: 12021
With @WebMvcTest
you still get an application context, but not the full application context.
The started Spring Test Context only contains beans that are relevant for testing your Spring MVC components: @Controller
, @ControllerAdvice
, Converter
, Filter
, WebMvcConfigurer
.
Injecting MockMvc
using @Autowired MockMvc mockMvc;
also indicates that you are working with a Spring context and the JUnit Jupiter extension (@ExtendWith(SpringExtension.class
which is part of @WebMvcTest
) takes care to resolve your fields by retrieving them from the Test context.
If you still don't want a Spring Test context to be started, you can write a unit test using only JUnit and Mockito. With such tests, you would only be able to verify the business logic of your controller and not things like: correct HTTP response, path variable and query parameter resolving, exception handling with different HTTP status, etc.
You can read more on the different Spring Boot Test slices here and on how to use MockMvc
to test your web layer.
Upvotes: 4