简体   繁体   English

Spring Controller测试随机失败

[英]Spring Controller Tests failing randomly

There is a project with 20 controllers approximately. 大约有20个控制器的项目。 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. 如果任何控制器测试类都用@Ignore注释,则测试将恢复正常。

This is the exception thrown by the failing tests: 这是失败的测试引发的异常:

org.springframework.web.util.NestedServletException: Request processing failed; org.springframework.web.util.NestedServletException:请求处理失败; nested exception is java.lang.IllegalStateException: org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf has been closed already. 嵌套异常是java.lang.IllegalStateException:org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf已经关闭。

Full log of one failing test: 一项失败测试的完整日志:

:: Spring Boot :: (v2.0.3.RELEASE) :: Spring Boot ::(v2.0.3.RELEASE)

2019-07-04T13:01:50,325 INFO [pool-1-thread-17] osbStartupInfoLogger: 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] osbStartupInfoLogger: Running with Spring Boot v2.0.3.RELEASE, Spring v5.0.7.RELEASE 2019-07-04T13:01:50,325 INFO [pool-1-thread-17] osbSpringApplication: No active profile set, falling back to default profiles: default 2019-07-04T13:01:50,326 INFO [pool-1-thread-17] oscsAbstractApplicationContext: Refreshing org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92: startup date [Thu Jul 04 13:01:50 ART 2019]; 2019-07-04T13:01:50,325信息[pool-1-thread-17] osbStartupInfoLogger:使用PID 17817在valhala上启动ZipCodeControllerTest(由/ home / wblanck / Projects / project中的wblanck启动)2019-07-04T13:01: 50,325 DEBUG [pool-1-thread-17] osbStartupInfoLogger:使用Spring Boot v2.0.3.RELEASE,Spring v5.0.7.RELEASE运行2019-07-04T13:01:50,325 INFO [pool-1-thread-17] osbSpringApplication:未设置活动的配置文件,恢复为默认配置文件:默认2019-07-04T13:01:50,326 INFO [pool-1-thread-17] oscsAbstractApplicationContext:刷新org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92:启动日期[Thu Jul 04 13:01:50 ART 2019]; root of context hierarchy 2019-07-04T13:01:50,448 INFO [pool-1-thread-17] osbfaAutowiredAnnotationBeanPostProcessor: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 上下文层次结构的根2019-07-04T13:01:50,448信息[pool-1-thread-17] osbfaAutowiredAnnotationBeanPostProcessor:找到并支持JSR-330'javax.inject.Inject'注释以进行自动装配

2019-07-04T13:01:50,772 INFO [pool-1-thread-17] oswshAbstractHandlerMethodMapping$MappingRegistry: Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity com.package.controller.WrongPathErrorController.badPathError(javax.servlet.http.HttpServletRequest) 2019-07-04T13:01:50,772 INFO [pool-1-thread-17] oswshAbstractHandlerMethodMapping$MappingRegistry: Mapped "{[/api/users/{device}/zip-code],methods=[GET],produces=[application/json]}" onto public org.springframework.http.ResponseEntity com.package.controller.ZipCodeController.checkZipCode(java.lang.Integer,java.lang.String,java.lang.String,java.lang.Integer,java.lang.String) 2019-07-04T13:01,50,772信息[pool-1-thread-17] oswshAbstractHandlerMethodMapping $ MappingRegistry:将“ {[/ error]}”映射到公共org.springframework.http.ResponseEntity com.package.controller.WrongPathErrorController.badPathError (javax.servlet.http.HttpServletRequest)2019-07-04T13:01:50,772信息[pool-1-thread-17] oswshAbstractHandlerMethodMapping $ MappingRegistry:映射了“ {[/ api / users / {device} / zip-code],方法= [GET],产生= [application / json]}“到公共org.springframework.http.ResponseEntity com.package.controller.ZipCodeController.checkZipCode(java.lang.Integer,java.lang.String,java.lang。串,为java.lang.Integer,java.lang.String中)

... more HandlerMethodMappings ... ...更多HandlerMethodMappings ...

2019-07-04T13:01:50,773 INFO [pool-1-thread-17] oswshAbstractHandlerMethodMapping$MappingRegistry: Mapped "{[/swagger-resources/configuration/ui]}" onto public org.springframework.http.ResponseEntity springfox.documentation.swagger.web.ApiResourceController.uiConfiguration() 2019-07-04T13:01:50,773 INFO [pool-1-thread-17] oswshAbstractHandlerMethodMapping$MappingRegistry: Mapped "{[/swagger-resources]}" onto public org.springframework.http.ResponseEntity> springfox.documentation.swagger.web.ApiResourceController.swaggerResources() 2019-07-04T13:01:50,773 INFO [pool-1-thread-17] oswshAbstractHandlerMethodMapping$MappingRegistry: Mapped "{[/swagger-resources/configuration/security]}" onto public org.springframework.http.ResponseEntity springfox.documentation.swagger.web.ApiResourceController.securityConfiguration() 2019-07-04T13:01:50,824 INFO [pool-1-thread-17] sdswPropertySourcedRequestMappingHandlerMapping: Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.Re 2019-07-04T13:01:50,773信息[pool-1-thread-17] oswshAbstractHandlerMethodMapping $ MappingRegistry:将“ {[/ swagger-resources / configuration / ui]}”映射到公共org.springframework.http.ResponseEntity springfox.documentation .swagger.web.ApiResourceController.uiConfiguration()2019-07-04T13:01:50,773信息[pool-1-thread-17] oswshAbstractHandlerMethodMapping $ MappingRegistry:将“ {{/ swagger-resources]}”映射到公共org.springframework。 http.ResponseEntity> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()2019-07-04T13:01:50,773 INFO [pool-1-thread-17] oswshAbstractHandlerMethodMapping $ MappingRegistry:Mapped“ {[/ swagger-resources / configuration / security]}“到公共org.springframework.http.ResponseEntity springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()2019-07-04T13:01:50,824信息[pool-1-thread-17] sdswPropertySourcedRequestMappingHandlerMapping:映射的URL方法[public org.springframework.http.Re上的路径[/ v2 / api-docs] sponseEntity springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)] 2019-07-04T13:01:50,859 INFO [pool-1-thread-17] oswshAbstractUrlHandlerMapping: 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] oswsmmaRequestMappingHandlerAdapter: Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92: startup date [Thu Jul 04 13:01:50 ART 2019]; sponseEntity springfox.documentation.swagger2.web.Sw​​agger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)] 2019-07-04T13:01:50,859信息[pool-1-thread-17] oswshAbstractUrlHandlerMapping:Mapped 类型为[class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]的处理程序上的 URL路径[/ /favicon.ico] 2019-07-04T13:01:50,913信息[pool-1-thread-17] oswsmmaRequestMappingHandlerAdapter:寻找@ControllerAdvice:org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92:启动日期[Thu Jul 04 13:01:50 ART 2019]; root of context hierarchy 2019-07-04T13:01:50,931 INFO [pool-1-thread-17] oswshAbstractUrlHandlerMapping: 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] oswshAbstractUrlHandlerMapping: 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] oswsmmaExceptionHandlerExceptionResolver: Detected @ExceptionHandler methods in integrationExceptionHandler 2019-07-04T13:01:50,981 INFO [pool-1-thread-17] osmwMockServletContext: Initializing Spring FrameworkServlet '' 2019-07-04T13:01:50,981 INFO [pool-1-thread-17] oswsFrameworkServlet: FrameworkServlet '': initialization started 2019-07-04T13:01:50,987 INFO [pool-1-thread-17] oswsFrameworkServlet: FrameworkServlet '': initialization completed in 6 ms 2019-07-04T13:01:50,995 INFO [pool-1-thread-17] oscsDefaultLife 上下文层次结构的根2019-07-04T13:01:50,931信息[pool-1-thread-17] oswshAbstractUrlHandlerMapping:将URL路径[/ webjars / ] 映射到类型为[class org.springframework.web.servlet.resource.ResourceHttpRequestHandler的处理程序上] 2019-07-04T13:01:50,931信息[pool-1-thread-17] oswshAbstractUrlHandlerMapping:将URL路径[/ **]映射到类型为[class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]的处理程序上2019- 07-04T13:01:50,938信息[pool-1-thread-17] oswsmmaExceptionHandlerExceptionResolver:在integrationExceptionHandler中检测到@ExceptionHandler方法2019-07-04T13:01:50,981信息[pool-1-thread-17] osmwMockServletContext:初始化Spring FrameworkServlet' '2019-07-04T13:01:50,981信息[pool-1-thread-17] oswsFrameworkServlet:FrameworkServlet'':初始化开始于2019-07-04T13:01:50,987信息[pool-1-thread-17] oswsFrameworkServlet:FrameworkServlet '':初始化在6毫秒内完成2019-07-04T13:01:50,995 INFO [pool-1-thread-17] oscsDefaultLife cycleProcessor$LifecycleGroup: Starting beans in phase 2147483647 2019-07-04T13:01:50,995 INFO [pool-1-thread-17] sdswpDocumentationPluginsBootstrapper: Context refreshed 2019-07-04T13:01:50,995 INFO [pool-1-thread-17] sdswpDocumentationPluginsBootstrapper: Found 1 custom documentation plugin(s) 2019-07-04T13:01:50,999 INFO [pool-1-thread-17] sdswsApiListingReferenceScanner: Scanning for api listing references 2019-07-04T13:01:51,109 INFO [pool-1-thread-17] osbStartupInfoLogger: Started ZipCodeControllerTest in 0.813 seconds (JVM running for 39.78) 2019-07-04T13:01:51,111 INFO [pool-1-thread-17] oscsAbstractApplicationContext: Closing org.springframework.web.context.support.GenericWebApplicationContext@40554129: startup date [Thu Jul 04 13:01:42 ART 2019]; cycleProcessor $ LifecycleGroup:在阶段2147483647中启动bean 2019-07-04T13:01:50,995 INFO [pool-1-thread-17] sdswpDocumentationPluginsBootstrapper:上下文刷新了2019-07-04T13:01:50,995 INFO [pool-1-thread-17 ] sdswpDocumentationPluginsBootstrapper:找到1个自定义文档插件2019-07-04T13:01:50,999信息[pool-1-thread-17] sdswsApiListingReferenceScanner:扫描api列表引用2019-07-04T13:01:51,109信息[pool- [1-thread-17] osbStartupInfoLogger:在0.813秒内启动ZipCodeControllerTest(JVM运行39.78)2019-07-04T13:01:51,111信息[pool-1-thread-17] oscsAbstractApplicationContext:关闭org.springframework.web.context.support .GenericWebApplicationContext @ 40554129:启动日期[Thu Jul 04 13:01:42 ART 2019]; root of context hierarchy 2019-07-04T13:01:51,112 INFO [pool-1-thread-17] oscsDefaultLifecycleProcessor$LifecycleGroup: Stopping beans in phase 2147483647 Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 14.141 s <<< FAILURE! 上下文层次结构的根2019-07-04T13:01:51,112信息[pool-1-thread-17] oscsDefaultLifecycleProcessor $ LifecycleGroup:在阶段2147483647中停止bean测试运行:3,失败:0,错误:1,跳过:0,时间经过时间:14.141 s <<<故障! - in com.package.controller.ZipCodeControllerTest testInexistentCheckZipCode(com.package.controller.ZipCodeControllerTest) Time elapsed: 10.648 s <<< ERROR! -com.package.controller.ZipCodeControllerTest中的testInexistentCheckZipCode(com.package.controller.ZipCodeControllerTest)经过的时间:10.648 s <<<错误! org.springframework.web.util.NestedServletException: Request processing failed; org.springframework.web.util.NestedServletException:请求处理失败; 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) 嵌套异常是java.lang.IllegalStateException:org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf已经在com.package.controller.ZipCodeControllerTest.testInexistentCheckZipCode(ZipCodeControllerTest.java:80)处关闭。 IllegalStateException:org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf已在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. 由于机密性,我更改了类和变量的名称。

You should use DirtiesContext annotation on your tests. 您应该在测试中使用DirtiesContext批注。 This will assure you'll get clean context on each test and they will not not interfere with eachother 这将确保您在每次测试时都能获得清晰的环境,并且它们不会互相干扰

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM