在我们的项目中,我们将@AutoConfigureMockMvc
与 printOnlyOnFailure
一起使用,默认为true
。
这可以正常工作,并且没有打印任何请求……除非有任何测试失败。那时,它从> >所有测试中打印 able 请求。尽管这有时可能很有用,但这可能会打印大量日志,如果它发生在我们的CI服务器上,则日志被截断了,我们甚至看不到哪个测试失败(因为后来打印了AssertionError
。
更糟:如果多个测试失败,则为每个失败测试打印所有先前的请求。
是否可以配置它,以使其仅打印失败测试的请求?
这是重现问题的样本测试:
@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 {
}
}
我们使用的是Spring-Boot 1.5.14和Java 8.我还以Spring-Boot 2.1.4。
从我能找到的,日志线存储在org.springframework.boot.test.autoconfigure.web.servlet.SpringBootMockMvcBuilderCustomizer.DeferredLinesWriter.lines
中,永远不会重置,也似乎没有一种重置方法 - 我宁愿避免通过反射进行。
所以我试图进一步研究SpringBootMockMvcBuilderCustomizer
实现,并且一切似乎都是private
或protected
,以防止重复使用任何内容(甚至不确定您可以重复使用PrintingResultHandler
本身,由于唯一的构造函数是protected
(。
使用反射并不难,将其添加到测试中:
@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();
}
不是很干净,可能会在未来版本的Spring Boot中破裂,但它起作用。
我希望能够实施更好的解决方案,但恐怕这是不可能的。
我不确定是否有人对此感兴趣,但我记得几年前,我在另一个非春季启动项目上,可能是在引入printOnlyOnFailure
选项之前真正了解为什么它在v5.0.5
上打印了以前执行的测试(我尚未测试更高版本(
就像您一样,我今天需要回到一个较新的项目上,花了几个小时才提醒我是如何做到的,我想我也发现了stackoverflow上的最初想法,所以这是一个简短的答案,试图将其复活。好主意(我目前不在来源前面,但可以随意询问实施,只需使用junit4或junit5而没有反思(
(简短答案:
- 注册junit5 testwatcher
- 覆盖
testFailed()
方法 - 当您的Junit测试执行时,存储MockMVC结果
- 失败,致电
print().handle(result.andReturn())
- 用
@AutoConfigureMockMvc(print = MockMvcPrint.NONE)
注释您的测试摘要/配置
结果是保存的最后一个测试失败的实例。
不利的一面是您必须像这样写测试
result = mvc
.perform();
result
.andExpect()
.andExpect();
不是完美的,但是我发现这种方式比使用反射更优雅:(