Spring Controller测试随机失败

时间:2019-07-04 16:35:45

标签: java spring spring-boot junit

一个大约有20个控制器的项目。每个控制器都有其相应的测试类别。 当我们尝试添加新的控制器测试类时,某些运行良好的先前测试开始随机失败。如果任何控制器测试类都用@Ignore注释,则测试将恢复正常。

这是测试失败所引发的异常:

  

org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是java.lang.IllegalStateException:org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf已经关闭。

一项失败的测试的完整日志:

  

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

     

2019-07-04T13:01:50,325 INFO [pool-1-thread-17]   o.s.b.StartupInfoLogger:在valhala上启动ZipCodeControllerTest   使用PID 17817(由/ home / wblanck / Projects / project中的wblanck开头)   2019-07-04T13:01:50,325 DEBUG [pool-1-thread-17]   o.s.b. StartupInfoLogger:使用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:未设置有效的配置文件,回退到   默认配置文件:默认2019-07-04T13:01:50,326信息   [pool-1-thread-17] o.s.c.s.AbstractApplicationContext:刷新   org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92:   启动日期[2019年7月4日星期四13:01:50 ART];上下文层次结构的根   2019-07-04T13:01:50,448 INFO [pool-1-thread-17]   o.s.b.f.a.AutowiredAnnotationBeanPostProcessor:JSR-330   找到并支持自动装配的'javax.inject.Inject'注释

     

2019-07-04T13:01:50,772信息[pool-1-thread-17]   o.s.w.s.h.Abs​​tractHandlerMethodMapping $ 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]   o.s.w.s.h.Abs​​tractHandlerMethodMapping $ MappingRegistry:已映射   “ {[/ api / users / {device} /邮政编码],方法= [GET],produces = [application / json]}”   公开   org.springframework.http.ResponseEntity   com.package.controller.ZipCodeController.checkZipCode(java.lang.Integer,java.lang.String,java.lang.String,java.lang.Integer,java.lang.String)

     

...更多HandlerMethodMappings ...

     

2019-07-04T13:01:50,773信息[pool-1-thread-17]   o.s.w.s.h.Abs​​tractHandlerMethodMapping $ MappingRegistry:已映射   “ {[/ swagger-resources / configuration / ui]}”公开   org.springframework.http.ResponseEntity   springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()   2019-07-04T13:01:50,773 INFO [pool-1-thread-17]   o.s.w.s.h.Abs​​tractHandlerMethodMapping $ MappingRegistry:已映射   “ {[/ swagger-resources]}”公开发布   org.springframework.http.ResponseEntity>   springfox.documentation.swagger.web.ApiResourceController.swaggerResources()   2019-07-04T13:01:50,773 INFO [pool-1-thread-17]   o.s.w.s.h.Abs​​tractHandlerMethodMapping $ MappingRegistry:已映射   “ {[/ swagger-resources / configuration / security]}”公开发布   org.springframework.http.ResponseEntity   springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()   2019-07-04T13:01:50,824信息[pool-1-thread-17]   s.d.s.w.PropertySourcedRequestMappingHandlerMapping:映射的URL路径   [/ v2 / api-docs]转到方法[public   org.springframework.http.ResponseEntity   springfox.documentation.swagger2.web.Sw​​agger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]   2019-07-04T13:01:50,859 INFO [pool-1-thread-17]   o.s.w.s.h.Abs​​tractUrlHandlerMapping:映射的URL路径[//favicon.ico]   到类型[class   org.springframework.web.servlet.resource.ResourceHttpRequestHandler]   2019-07-04T13:01:50,913信息[pool-1-thread-17]   o.s.w.s.m.m.a.RequestMappingHandlerAdapter:寻找   @ControllerAdvice:   org.springframework.web.context.support.GenericWebApplicationContext@a5a2b92:   启动日期[2019年7月4日星期四13:01:50 ART];上下文层次结构的根   2019-07-04T13:01:50,931信息[pool-1-thread-17]   o.s.w.s.h.Abs​​tractUrlHandlerMapping:映射的URL路径[/ webjars / ]   到类型[class   org.springframework.web.servlet.resource.ResourceHttpRequestHandler]   2019-07-04T13:01:50,931信息[pool-1-thread-17]   o.s.w.s.h.Abs​​tractUrlHandlerMapping:将URL路径[/ **]映射到   类型的处理程序   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:检测到   IntegrationExceptionHandler中的@ExceptionHandler方法   2019-07-04T13:01:50,981信息[pool-1-thread-17]   o.s.m.w.MockServletContext:初始化Spring FrameworkServlet''   2019-07-04T13:01:50,981信息[pool-1-thread-17]   o.s.w.s.FrameworkServlet:FrameworkServlet'':初始化已开始   2019-07-04T13:01:50,987 INFO [pool-1-thread-17]   o.s.w.s.FrameworkServlet:FrameworkServlet'':初始化   于6 ms中完成2019-07-04T13:01:50,995 INFO [pool-1-thread-17]   o.s.c.s.DefaultLifecycleProcessor $ LifecycleGroup:在以下位置启动bean   阶段2147483647 2019-07-04T13:01:50,995 INFO [pool-1-thread-17]   s.d.s.w.p.DocumentationPluginsBootstrapper:上下文已刷新   2019-07-04T13:01:50,995 INFO [pool-1-thread-17]   s.d.s.w.p.DocumentationPluginsBootstrapper:找到1个自定义   文档插件2019-07-04T13:01:50,999 INFO   [pool-1-thread-17] s.d.s.w.s.ApiListingReferenceScanner:正在扫描   api清单参考2019-07-04T13:01:51,109信息   [pool-1-thread-17] o.s.b.StartupInfoLogger:已启动   ZipCodeControllerTest在0.813秒内运行(JVM运行39.78)   2019-07-04T13:01:51,111 INFO [pool-1-thread-17]   o.s.c.s.AbstractApplicationContext:关闭   org.springframework.web.context.support.GenericWebApplicationContext@40554129:   启动日期[2019年7月4日星期四13:01:42 ART];上下文层次结构的根   2019-07-04T13:01:51,112 INFO [pool-1-thread-17]   o.s.c.s.DefaultLifecycleProcessor $ LifecycleGroup:在中停止Bean   阶段2147483647测试运行:3,失败:0,错误:1,跳过:0,   经过的时间:14.141 s <<<故障! -在   com.package.controller.ZipCodeControllerTest   testInexistentCheckZipCode(com.package.controller.ZipCodeControllerTest)   经过的时间:10.648 s <<<错误!   org.springframework.web.util.NestedServletException:请求   处理失败;嵌套异常为   java.lang.IllegalStateException:   org.springframework.web.context.support.GenericWebApplicationContext@22f3fadf   已在关闭   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)

测试非常相似,基本上常见的结构是:


@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());
    }

控制器具有如下结构:

@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);
    }


我无法理解这些异常的原因以及它们在每次运行的不同测试中都会发生的事实。

由于机密性,我更改了类和变量的名称。

1 个答案:

答案 0 :(得分:0)

您应该在测试中使用DirtiesContext批注。这样可以确保您在每次测试时都能获得清晰的背景信息,并且不会互相干扰