Reputation: 51
There is a project with 20 controllers approximately. Each controller has its corresponding test class. When we try to add new controller tests classes, some of the previous tests which were running fine, starts to fail randomly. If any controller test class is annotated with @Ignore, tests get back to normal.
This is the exception thrown by the failing tests:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf has been closed already.
Full log of one failing test:
:: Spring Boot :: (v2.0.3.RELEASE)
2019-07-04T13:01:50,325 INFO [pool-1-thread-17]
o.s.b.StartupInfoLogger: Starting ZipCodeControllerTest on valhala
with PID 17817 (started by wblanck in /home/wblanck/Projects/project)
2019-07-04T13:01:50,325 DEBUG [pool-1-thread-17]
o.s.b.StartupInfoLogger: Running with Spring Boot v2.0.3.RELEASE,
Spring v5.0.7.RELEASE 2019-07-04T13:01:50,325 INFO [pool-1-thread-17]
o.s.b.SpringApplication: No active profile set, falling back to
default profiles: default 2019-07-04T13:01:50,326 INFO
[pool-1-thread-17] o.s.c.s.AbstractApplicationContext: Refreshing
org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92:
startup date [Thu Jul 04 13:01:50 ART 2019]; root of context hierarchy
2019-07-04T13:01:50,448 INFO [pool-1-thread-17]
o.s.b.f.a.AutowiredAnnotationBeanPostProcessor: JSR-330
'javax.inject.Inject' annotation found and supported for autowiring
2019-07-04T13:01:50,772 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractHandlerMethodMapping$MappingRegistry: Mapped
"{[/error]}" onto public
org.springframework.http.ResponseEntity<java.lang.Object>
com.package.controller.WrongPathErrorController.badPathError(javax.servlet.http.HttpServletRequest)
2019-07-04T13:01:50,772 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractHandlerMethodMapping$MappingRegistry: Mapped
"{[/api/users/{device}/zip-code],methods=[GET],produces=[application/json]}"
onto public
org.springframework.http.ResponseEntity<com.package.entity.CheckZipCodeProcedureResponseStatus>
com.package.controller.ZipCodeController.checkZipCode(java.lang.Integer,java.lang.String,java.lang.String,java.lang.Integer,java.lang.String)
... more HandlerMethodMappings ...
2019-07-04T13:01:50,773 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractHandlerMethodMapping$MappingRegistry: Mapped
"{[/swagger-resources/configuration/ui]}" onto public
org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration>
springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
2019-07-04T13:01:50,773 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractHandlerMethodMapping$MappingRegistry: Mapped
"{[/swagger-resources]}" onto public
org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>>
springfox.documentation.swagger.web.ApiResourceController.swaggerResources()
2019-07-04T13:01:50,773 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractHandlerMethodMapping$MappingRegistry: Mapped
"{[/swagger-resources/configuration/security]}" onto public
org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration>
springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
2019-07-04T13:01:50,824 INFO [pool-1-thread-17]
s.d.s.w.PropertySourcedRequestMappingHandlerMapping: Mapped URL path
[/v2/api-docs] onto method [public
org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json>
springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
2019-07-04T13:01:50,859 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractUrlHandlerMapping: Mapped URL path [/**/favicon.ico]
onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-07-04T13:01:50,913 INFO [pool-1-thread-17]
o.s.w.s.m.m.a.RequestMappingHandlerAdapter: Looking for
@ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92:
startup date [Thu Jul 04 13:01:50 ART 2019]; root of context hierarchy
2019-07-04T13:01:50,931 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractUrlHandlerMapping: Mapped URL path [/webjars/**]
onto handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-07-04T13:01:50,931 INFO [pool-1-thread-17]
o.s.w.s.h.AbstractUrlHandlerMapping: Mapped URL path [/**] onto
handler of type [class
org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-07-04T13:01:50,938 INFO [pool-1-thread-17]
o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver: Detected
@ExceptionHandler methods in integrationExceptionHandler
2019-07-04T13:01:50,981 INFO [pool-1-thread-17]
o.s.m.w.MockServletContext: Initializing Spring FrameworkServlet ''
2019-07-04T13:01:50,981 INFO [pool-1-thread-17]
o.s.w.s.FrameworkServlet: FrameworkServlet '': initialization started
2019-07-04T13:01:50,987 INFO [pool-1-thread-17]
o.s.w.s.FrameworkServlet: FrameworkServlet '': initialization
completed in 6 ms 2019-07-04T13:01:50,995 INFO [pool-1-thread-17]
o.s.c.s.DefaultLifecycleProcessor$LifecycleGroup: Starting beans in
phase 2147483647 2019-07-04T13:01:50,995 INFO [pool-1-thread-17]
s.d.s.w.p.DocumentationPluginsBootstrapper: Context refreshed
2019-07-04T13:01:50,995 INFO [pool-1-thread-17]
s.d.s.w.p.DocumentationPluginsBootstrapper: Found 1 custom
documentation plugin(s) 2019-07-04T13:01:50,999 INFO
[pool-1-thread-17] s.d.s.w.s.ApiListingReferenceScanner: Scanning for
api listing references 2019-07-04T13:01:51,109 INFO
[pool-1-thread-17] o.s.b.StartupInfoLogger: Started
ZipCodeControllerTest in 0.813 seconds (JVM running for 39.78)
2019-07-04T13:01:51,111 INFO [pool-1-thread-17]
o.s.c.s.AbstractApplicationContext: Closing
org.springframework.web.context.support.GenericWebApplicationContext@40554129:
startup date [Thu Jul 04 13:01:42 ART 2019]; root of context hierarchy
2019-07-04T13:01:51,112 INFO [pool-1-thread-17]
o.s.c.s.DefaultLifecycleProcessor$LifecycleGroup: Stopping beans in
phase 2147483647 Tests run: 3, Failures: 0, Errors: 1, Skipped: 0,
Time elapsed: 14.141 s <<< FAILURE! - in
com.package.controller.ZipCodeControllerTest
testInexistentCheckZipCode(com.package.controller.ZipCodeControllerTest)
Time elapsed: 10.648 s <<< ERROR!
org.springframework.web.util.NestedServletException: Request
processing failed; nested exception is
java.lang.IllegalStateException:
org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf
has been closed already at
com.package.controller.ZipCodeControllerTest.testInexistentCheckZipCode(ZipCodeControllerTest.java:80)
Caused by: java.lang.IllegalStateException:
org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf
has been closed already at
com.package.controller.ZipCodeControllerTest.testInexistentCheckZipCode(ZipCodeControllerTest.java:80)
Tests are very similar, basically the common structure is:
@RunWith(SpringRunner.class)
@WebMvcTest(Controller.class)
public class ControllerTest {
private static final String URL_TEMPLATE = ".....";
@Autowired
private MockMvc mvc;
@Autowired
private ObjectMapper mapper;
@MockBean
private Service service;
private CustomParams params;
private CustomRequest request;
@Before
public void init() {
// initialize params and request ...
}
@Test
public void methodOk() throws Exception {
when(service.method(refEq(params))).thenReturn(RESPONSE);
mvc.perform(MockMvcRequestBuilders.post(URL_TEMPLATE)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(mapper.writeValueAsString(request)))
.andExpect(status().isOk())
.andExpect(jsonPath(STATUS_MESSAGE_PATH, is(MESSAGE_CODE_OK)))
.andExpect(jsonPath(STATUS_CODE_PATH, is(STATUS_OK.getStatusCode()))));
}
@Test
public void badRequest() throws Exception {
mvc.perform(MockMvcRequestBuilders.post(URL_TEMPLATE))
.andExpect(status().isBadRequest())
.andExpect(jsonPath(ERROR_MESSAGE_PATH).isNotEmpty());
}
Controllers have a structure like the following:
@RestController
public class Controller {
private Service service;
@PostMapping(value = "/api/some-url", produces = {"application/json"})
public ResponseEntity<CustomResponse> method(
@RequestHeader("someheaders") Integer someHeaders,
@RequestBody CustomRequest someBody) {
CustomParams params = new CustomParams();
params.setApplicationType(applicationType);
params.someHeaders(someHeaders);
return service.method(params);
}
I can't understand the reason of the exceptions and the fact that they occur in different tests in each run.
I've changed classes and variable's names due to confidentiality.
Upvotes: 5
Views: 5621
Reputation: 12953
You should use DirtiesContext annotation on your tests. This will assure you'll get clean context on each test and they will not not interfere with eachother
Upvotes: 3