问题
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