Поскольку я не получил ответа на свой другой вопрос здесь, я ищу другой подход. Есть ли способ не выполнять или включать фрагмент во время модульного тестирования?
Я хочу отображать версию и номер сборки в нижнем колонтитуле моих шаблонов, поэтому у меня есть следующая строка:
<div class = "versionInfo">Version <span th:text = "${@buildProperties.getVersion()}"></span></div>
Это хорошо работает при запуске приложения, но во время модульного теста я получаю исключение:
No bean named 'buildProperties' available
В другом вопросе я ищу способ получить этот bean-компонент во время модульного тестирования, в качестве альтернативы я сейчас ищу способ исключить этот шаблон во время модульных тестов. Что-то вроде этого:
<div class = "versionInfo" th:if = "${!isUnitTest}">Version <span th:text = "${@buildProperties.getVersion()}"></span></div>
Я использую следующие аннотации в своем тестовом классе:
@RunWith(SpringRunner.class)
@WebMvcTest(SimpleController.class)
Проблема с buildProperties в том, что это автоматическая вещь с весны, когда она построена: docs.spring.io/spring-boot/docs/current/reference/html/…
Используете ли вы @SpringBootTest в тестовом классе?
@MebinJoe Нет, я использую @WebMvcTest as. Я также пробовал это с @SpringBootTest, но тогда MockMvc не работает, как ожидалось.
какое исключение вы получаете?
@MebinJoe Давайте не будем обсуждать эту проблему в этом билете. Взгляните на другой stackoverflow.com/questions/54712564/… и посмотрите мой комментарий здесь: stackoverflow.com/questions/48078044/…





Если это стандартный модульный тест, используйте Mockito для имитации компонента:
@RunWith(MockitoJUnitRunner.class)
public class SomeTest{
@Mock
private BuildProperties buildProperties;
...
Или, если это тест Spring MVC:
@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class)
public class MyControllerTest{
@MockBean
private BuildProperties buildProperties;
Версия будет null, потому что все методы фиктивного компонента возвращают null.
если вы хотите эмулировать реальную версию, вы можете добавить что-то подобное в свой тест или в метод setUp()
given(buildProperties.getVersion()).willReturn("whatever");
--------------- редактировать
К сожалению, все вышеперечисленные решения работают только в том случае, если bean-компонент buildProperties был добавлен в модель напрямую. Но в вашем случае вы используете bean-компонент напрямую в качестве ссылки на bean-компонент SpEL. К сожалению, я не знаю, как проверить, существует ли компонент в контексте через SpEL. Кроме того, не рекомендуется добавлять в код дополнительный код для проверки, работает ли он в тестовом режиме. Поэтому я считаю лучшим решением, если вы создадите вложенный класс конфигурации теста и определите там bean-компонент BuildProperties по умолчанию.
@TestConfiguration
public static class TestConfig {
@Bean
BuildProperties buildProperties() {
return new BuildProperties(new Properties());
}
}
Или вы можете использовать @Import(TestConfig.class), если вам нужна эта дополнительная конфигурация в нескольких тестовых классах.
Я пробовал это, но все равно получаю ту же ошибку, упомянутую в моем OP.
Хорошо, ваше редактирование помогло мне. Для полноты, возможно, добавьте, что вы можете использовать @Import(TestConfig.class) в своих тестовых классах, поэтому вам не нужно его встраивать.
Если вам нужны дополнительные баллы, опубликуйте свой отредактированный ответ на мой другой вопрос (на самом деле вы ответили на этот вопрос, а не на этот, но тем не менее я его принял): stackoverflow.com/questions/54712564/…
Я получил подсказку от коллеги, который работает над этим вопросом.
Просто добавьте application.properties к src/test/resources с пользовательским свойством:
isUnitTest=true
Затем я могу просто проверить это в своем шаблоне тимелеафа:
<div class = "versionInfo" th:if = "${@environment.getProperty('isUnitTest') != 'true'}">Version <span th:text = "${@buildProperties.getVersion()}"></span></div>
Хотя, если кто-то найдет способ добиться этого автоматически с помощью настройки или свойства тимелеафа, которое я пока не нашел, я приму это как ответ.
Добавление дополнительного кода для тестирования, если код выполняется как тест, никогда не является хорошей идеей. Проверьте мой отредактированный ответ
Да, я знаю об этом, но пока это обходной путь. Я проверю ваше другое предложение.
Не могли бы вы поделиться кодом Java. 1. Вы выполнили автосвязывание класса и доступны ли свойства buildProperties в контексте? 2. Использовали ли вы Mock или какие-либо ReflectionTestUtils? ReflectionTestUtils.setField("yourClass", buildProperties, objectBuildProperties)