Модульное тестирование является неотъемлемой частью разработки проекта.В проекте SpringBoot мы используем@SpringBootTestАннотация используется для обозначения тестового класса, и каждый метод тестируется индивидуально после внедрения класса реализации этого интерфейса в тестовый класс.
Например, следующий пример тестового класса:
@SpringBootTest
public class HelloServiceTests {
@Autowired
private IHelloSerive helloService;
@Test
public void testHello() {
// ...
}
}
Но по мере роста объема кода в проекте вы обнаружите, что скорость запуска тестового класса становится все медленнее и медленнее, и в большинстве случаев это просто тестирование метода класса реализации, например, тестирование категории DAO.persistметод.
По факту,@SpringBootTestАннотация также предоставляет два параметра, правильное использование которых может ускорить запуск тестового класса.
1. webEnvironment
Это свойство определяет, должен ли тестовый класс запускатьwebСреда, грубо говоря, стоит ли начинатьTomcatконтейнер, необязательные значения:
- MOCK запускает фиктивную среду сервлета, которая используется по умолчанию.
- RANDOM_PORT, запустите контейнер Tomcat и прослушивайте случайный номер порта
- DEFINED_PORT, запустите контейнер Tomcat и прослушивайте порт, определенный в файле конфигурации (если он не определен, по умолчанию будет прослушиваться порт 8080).
- NONE, не запускать контейнер Tomcat
Если метод, который вы хотите протестировать, не требует контейнера Tomcat, например:
- Протестируйте CRUD для класса DAO
- Протестируйте бизнес-метод класса Service
- Протестируйте общедоступный метод класса Util
- Проверка того, что класс файла конфигурации считывает правильное значение
- ... ...
Просто указав@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)можно добиться эффекта ускорения. В это время при запуске тестового класса инициализируется только контекст Spring, а контейнер Tomcat больше не запускается:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class HelloServiceTests {
@Autowired
private IHelloSerive helloService;
@Test
public void testHello() {
// ...
}
}
2. classes
Атрибут классов используется для указания коллекции классов, которую необходимо загрузить для запуска тестового класса. Если он не указан, он будет загружен по умолчанию.@SpringBootConfigurationКласс аннотации аннотации.
упомянул@SpringBootConfigurationВы можете быть незнакомы, на самом деле@SpringBootApplicationЭта аннотация введена в исходный код:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
// ...
}
То есть, если мы не укажем атрибут классов, количество bean-компонентов, которые необходимо загрузить при запуске тестового класса, и начальный класс, который необходимо запустить в обычном режиме один раз (т.@SpringBootApplicationАннотированные классы) загружают одинаковое количество bean-компонентов.
Если в вашем проекте много бинов, особенно следующие:
- Существует класс реализации для CommandLineRunner.
- использовать
@PostConstructАннотировать класс, указывающий метод инициализации
Эти классы будут запускать свой собственный бизнес-код или код инициализации в процессе инициализации программы, тем самым задерживая выполнение тестового метода.
В этом случае, когда мы пишем тестовый класс, если мы знаем, какие бины будут использоваться этим тестовым классом, мы можем указать их в атрибуте классов, и тогда, когда мы запустим тестовый класс, в него будут загружены только нужные бины. контекст для более быстрого запуска. Например:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes={HelloServiceImpl.class})
public class HelloServiceTests {
@Autowired
private IHelloService helloService;
@Test
public void testHello() {
// ...
}
}
Даже если в это время в проекте есть другой Бин, в его методе инициализации что-то вродеThread.sleep(10000)И так далее не повлияет, т.к. бин вообще не загружается и не инициализируется.
Наконец, обратите внимание, что если ваша версия JUnit 4.x, вам также необходимо добавить новый тестовый класс.
@RunWith(SpringRunner.class)аннотация.