How to print only the requests of the failed test with @AutoConfigureMockMvc?

旧城冷巷雨未停 提交于 2019-12-08 05:12:54

问题


In our project we are using @AutoConfigureMockMvc with printOnlyOnFailure left as default, true.

This works fine and prints none of the requests… except if any test fails. At that point, it prints all requests from ALL tests that have been executed before. Although this might sometimes be useful, this may print an enormous amount of log, and if it happens on our CI server, the log gets truncated and we cannot even see which test failed (since the AssertionError is printed afterwards.

Even worse: if multiple tests fail, all previous requests are printed for each failing test.

Is it possible to configure it such that it will only print the requests of the failing tests?

Here is a sample test to reproduce the problem:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MockMvcTest {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void successfulTest() throws Exception {
        mockMvc.perform(get("/successfulTest"))
                .andExpect(status().isNotFound());
    }

    @Test
    public void failingTest() throws Exception {
        mockMvc.perform(get("/failingTest"))
                .andExpect(status().isOk());
    }

    @Test
    public void failingTest2() throws Exception {
        mockMvc.perform(get("/failingTest2"))
                .andExpect(status().isOk());
    }

    @Configuration
    static class TestApplication {
    }
}

We are using spring-boot 1.5.14 and Java 8. I also reproduced the problem with spring-boot 2.1.4.

From what I could find, the log lines are stored in org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.DeferredLinesWriter.lines and never get reset, nor does there seem to be a way to reset it – and I'd prefer to avoid doing it through reflexion.


回答1:


So I tried to dive a bit more into the SpringBootMockMvcBuilderCustomizer implementation and everything appears to be private or protected, preventing to reuse anything (not even sure you can reuse the PrintingResultHandler itself, which you are forced to extend since the only constructor is protected).

Using reflection is not too hard though, add this to the test:

@Autowired
private ApplicationContext context;
private Runnable linesWriterClearer;

@PostConstruct
public void initLinesWriterClearer() throws NoSuchFieldException, IllegalAccessException {
    Object linesWriter = context.getBean("org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer$DeferredLinesWriter");
    Field linesField = linesWriter.getClass().getDeclaredField("lines");
    linesField.setAccessible(true);
    List<?> lines = (List<?>) linesField.get(linesWriter);
    linesWriterClearer = lines::clear;
}

@Before
public void clearLinesWriter() {
    linesWriterClearer.run();
}

Not very clean and may probably break in a future version of Spring Boot, but it works.

I would hope a better solution could be implemented but I'm afraid it won't be possible.



来源:https://stackoverflow.com/questions/56294762/how-to-print-only-the-requests-of-the-failed-test-with-autoconfiguremockmvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!