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