Как распечатать только запросы неудачного теста с @AutoConfigureMockMvc? - PullRequest
1 голос
/ 24 мая 2019

В нашем проекте мы используем @AutoConfigureMockMvc с printOnlyOnFailure, оставленным по умолчанию, true.

Это работает нормально и не печатает ни одного из запросов ... за исключением случаев, когда какой-либо тест не пройден.В этот момент он печатает все запросы от ALL тестов, которые были выполнены ранее.Хотя это иногда может быть полезно, это может напечатать огромное количество журнала, и если это происходит на нашем 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 и никогда не сбрасываются, и, похоже, нет способа сбросить их - и я бы предпочел не делать этогочерез рефлексию.

1 Ответ

1 голос
/ 24 мая 2019

Итак, я попытался немного больше погрузиться в реализацию 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, но она работает.

Я надеюсь, что может быть реализовано лучшее решение, но, боюсь, это будет невозможно.

...