Автор оригинала: David Landup.
Вступление
Структура Spring – это очень надежная структура, выпущенная в 2002 году. Его основные функции могут быть применены к простым приложениям Java или расширены до сложных современных веб-приложений.
Поскольку он постоянно обновляется и следует новым архитектурным и программным парадигмам, он предлагает поддержку многих других фреймворков, которые работают рука об руку с ним.
С таким огромным набором функций вполне нормально, что он знакомит нас с некоторыми новыми аннотациями, которые являются ключевой частью разработки приложений Spring.
Конфигурация Spring полностью настраивается, что первоначально было сделано с помощью файлов конфигурации XML. Однако этот подход устарел, и в настоящее время большинство людей прибегают к настройке аннотаций.
Тем не менее, эта серия статей направлена на то, чтобы раскрыть возможности, которые вы, как разработчик, должны настроить и использовать Spring framework:
- Весенние аннотации: @RequestMapping и его варианты
- Весенние Аннотации: Аннотации основных рамок
- Весенние аннотации: Весеннее Облако
- Весенние Аннотации: Аннотации Testng
Аннотации к весеннему Тестированию
Разработка на основе тестов (TDD) в настоящее время стала важной темой, и считается крайне плохой практикой не проводить надлежащее тестирование ваших приложений.
Существует несколько широко используемых фреймворков, которые значительно облегчают эту работу разработчикам, где наиболее часто используется JUnit .
Чтобы соответствовать современным методам программирования, Spring запустила новую стартовую
зависимость spring-boot-starter-test
, которая состоит из нескольких фреймворков:
- Джунит
- Тест на пружину и Тест на пружинную загрузку
- Утверждение J
- Хамкрест
- Мокито
- JSONassert
- JSONPath
В этой статье мы рассмотрим следующие аннотации к тесту:
- @Начальная загрузка с
- @Контекстная конфигурация
- @Конфигурация веб-приложения
- @Контекстная иерархия
- @ActiveProfiles
- @Откат
- @Зафиксировать
- @BeforeTransaction
- @AfterTransaction
- @Sql
- @SqlGroup
- @SqlConfig
- @@Springboost
- @DataJpaTest
- @@Datamonitor
- @WebMvcTest
- @@Mockbeat
- @AutoConfigureMockMvc
- @JsonTest
- @TestPropertySource
- @Приурочено
- @Повтор
@Начальная загрузка с
Аннотация @BootstrapWith
– это аннотация, которую вы, скорее всего, будете использовать очень редко. Конфигурации по умолчанию для Spring TestContext Framework более чем достаточно хороши для большинства случаев использования.
Если это не так, вы можете изменить ContextLoader
или реализовать пользовательские TestContext
s среди множества других конфигураций, которые вы можете изменить.
Опять же, это аннотация, которую вы, скорее всего, не будете использовать, если вы не являетесь частью команды, которая действительно нуждается в пользовательской конфигурации для платформы Spring TestContext.
@Контекстная конфигурация
@ContextConfiguration
аннотация интеграционного теста, применяемая на уровне класса, используемая для определения того, как Spring должен загружать ApplicationContext
.
Эта аннотация может быть применена вместе с @Компонентом
(а также аннотациями, такими как @Сервис
, @Репозиторий
и т. Д.) И @Конфигурация
аннотации, а также любой класс, содержащий @Bean
s.
Вы можете использовать аннотацию для ссылки либо на XML-файлы, либо на классы Java:
@ContextConfiguration("/some-test-configuration-file.xml") // @ContetConfiguration(locations = "/some-test-configuration-file.xml") // You can use the optional `locations` flag as well. public class ApplicationTests { // Testing code... }
@ContextConfiguration(classes = TestConfiguration.class) public class ApplicationTests { // Testing code... }
Для примера предположим, что у нас есть testBean
:
@Configuration public class TestBean { @Bean public DeveloperService developerService() { return new DeveloperService(); } }
Если бы мы хотели сделать некоторые утверждения
в этом компоненте, мы бы сделали что-то вроде:
@ContextConfiguration(classes = TestBean.class) public class ApplicationTests { @Autowired private DeveloperService; @Test public void testBean() { Developer dev = developerService.getDeveloperById(5); assertEquals("David", dev.getName()); } }
В настоящее время предпочтительнее полагаться на классовый подход, поскольку XML обычно считается устаревшим подходом для регистрации компонентов. Если у вас есть более одного класса, конечно, вы бы просто указали их через classes = {TestBean.class, TestBean2.class, TestBean3.class}
и т.д.
Это подводит нас к аннотации @Test
, которая будет подробно рассмотрена ниже. А пока давайте просто используем его в целях иллюстрации.
@Конфигурация веб-приложения
Если вы хотите убедиться , что Spring загружает WebApplicationContext
для ваших тестов вместо обычного ApplicationContext
, вы можете использовать @WebAppConfiguration
аннотацию вместе с @ContextConfiguration
аннотацией:
@ContextConfiguration(classes = TestBean.class) @WebAppConfiguration public class ApplicationTests { @Autowired private DeveloperService; // Rest of the code... }
В качестве альтернативы вы можете указать флаг значение
или, скорее, местоположение WebApplicationContext
, если он не находится в каталоге по умолчанию src/main/webapp
:
@WebAppConfiguration("some/other/location") public class ApplicationTests {}
@Контекстная иерархия
Еще одна аннотация, которая обычно редко используется (я лично не видел, чтобы кто-либо использовал ее в проекте), – это @ContextHierarchy
аннотация.
Это позволяет разработчику определять несколько @контекстных конфигураций
на уровнях через отношения родитель-потомок|/.
Идея заключается в том, что дочерние контексты могут использовать компоненты, зарегистрированные в родительских контекстах, и это улучшает возможность повторного использования компонентов:
@ContextHierarchy({ @ContextConfiguration(classes = ApplicationTestConfiguration.class), @ContextConfiguration(classes = WebApplicationTestConfiguration.class) }) public class ApplicationTests { }
Если вы хотите прочитать больше об этой аннотации, документация содержит некоторую подробную информацию об иерархии контекста.
@ActiveProfiles
Аннотация @ActiveProfiles
– это довольно простая и понятная аннотация. Он определяет, какой профиль должен быть активен при загрузке конфигурации контекста:
@ContextConfiguration @ActiveProfiles("dev") public class ApplicationTests {}
Это указывает на то, что профиль “разработчик” должен быть активным.
Название аннотации подразумевает, что мы можем определить несколько профилей, которые мы можем:
@ContextConfiguration @ActiveProfiles({"dev", "prod"}) public class ApplicationTests {}
Если вы хотите узнать больше о профилях Spring , мы вас накроем!
@Откат
Иногда, имея дело с базами данных, мы хотим отменить внесенные изменения, особенно если мы вызвали исключение.
Аннотация @Rollback
определяет, следует ли откатывать транзакцию метода, помеченного символом @Transactional
, после завершения вызова метода тестирования.
Это может быть применено к уровню класса и метода:
- Уровень класса : Определяет откат по умолчанию для всех методов тестирования в классе
- Уровень метода : Определяет откат для конкретного метода тестирования
@Rollback(true) @Test public void someTest() { // ...calling some transactional method }
После завершения теста все изменения, внесенные транзакционным методом, будут откатаны.
Интересным моментом является тот факт , что вы можете установить необязательный флаг false
, в котором Spring гарантирует, что изменения не будут откатаны. Установка аннотации @Rollback
в false
будет вести себя точно так же, как @Commit
.
@Зафиксировать
В дополнение к предыдущему разделу, аннотация @Commit
используется, когда мы хотим убедиться в изменениях в базе данных после запуска методов тестирования.
Он ведет себя так же, как @Откат(ложь)
и может быть применен к уровню класса или метода:
@Commit @Test public void someTest() { // ...calling some transactional method }
@BeforeTransaction
Иногда мы хотим запустить определенные фрагменты кода до совершения транзакций. Для этого нам, очевидно, необходимо определить методы, специально написанные для этого.
Чтобы вызывать их перед каждой транзакцией, мы просто аннотируем их с помощью аннотации @BeforeTransaction
:
@BeforeTransaction void methodBeforeTransaction() { // ...ran before a transaction }
Для правильной работы аннотации вам необходимо пометить свои транзакционные методы с помощью @Transactional
.
Примечание : Начиная с весны 4.3, эти методы не должны быть общедоступными.
@AfterTransaction
Имея ту же природу, что и аннотация @BeforeTransaction
, аннотация @AfterTransaction
запускает определенный метод после совершения транзакции:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
@AfterTransaction void methodAfterTransaction() { // ...ran after a transaction }
Примечание : Начиная с весны 4.3, эти методы не должны быть общедоступными.
@Sql
Используя аннотацию @Sql
и передавая имена схем, которые мы хотим выполнить, мы можем программно(или декларативно) выполнять сценарии SQL.
По умолчанию эти сценарии запускаются перед любыми методами @Перед
.
Если мы определим сценарий, например создать таблицу.sql
:
CREATE TABLE ITEM (ITEM_ID INT PRIMARY KEY, ITEM_NAME VARCHAR(256) NOT NULL);
Мы можем ссылаться на него и легко его выполнять:
@Test @Sql("/createTable.sql") public void itemTest { // ...some code that depends on the sql script above }
@SqlGroup
Аннотация @SqlGroup
позволяет нам объединять несколько сценариев SQL и запускать их.
Если у нас есть другой сценарий, например, для удаления той же таблицы, drop Table.sql
:
DROP TABLE ITEM;
Мы можем объединить сценарий create Table.sql
со сценарием drop Table.sql
для запуска до и после метода тестирования, например:
@Test @SqlGroup({ @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = ""), @Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = ""), }) public void itemTest { // ...item table gets created, tested by the code and then dropped }
@SqlConfig
Как следует из названия, следуя стандартным примерам аннотаций Spring, аннотация @SqlConfig
используется для определения конфигурации сценариев SQL – как они анализируются и выполняются.
Он может быть применен на уровне класса или на уровне метода. Интеграционные тесты, которые требуют глобальной конфигурации для всех запущенных сценариев SQL, обычно используют подход на уровне классов, тогда как подход на уровне методов предназначен для локальных конфигураций определенных методов:
@Test @Sql(scripts = "/createTable.sql", config = @SqlConfig(attribute = "val", attribute2 = "val")) public void itemTest { // Some code... }
Существует 9 атрибутов, которые вы можете передать в аннотацию @SqlConfig
:
Разделитель комментариев к блоку
: Разделитель конца для комментариев к блокуРазделитель начала блока
: Разделитель начала для комментариев к блокупрефикс комментария
: Префикс для однострочных комментариевисточник данных
: Имяисточника данных
компоненткодировка
: Указание кодировки для сценариеврежим ошибки
: Какой режим использовать при обнаружении ошибкиразделитель
: Символ, используемый для разделения операторовдиспетчер транзакций
: Имя компонента диспетчера транзакцийрежим транзакции
: Какой режим использовать при выполнении SQL-скриптов
@@Springboost
В аннотации @SpringBootTest
выполняется поиск тестового класса, аннотированного @SpringBootConfiguration
, который в большинстве случаев является нашим основным классом приложения, поскольку @SpringBootApplication
включает в себя предыдущую аннотацию.
После обнаружения он создает контекст приложения для тестовой среды. Вы даже можете запустить веб-среду, используя атрибут веб-среда
:
@SpringBootTest public class IntegrationTests { // Rest of the code } @SpringBootTest(webEnvironment = pringBootTest.WebEnvironment.RANDOM_PORT) public class WebEnvIntegrationTests { // Rest of the code }
@DataJpaTest
Используя аннотацию @DataJpaTest
, мы можем тестировать приложения JPA. Он применяется на уровне классов и создает контекст приложения для всех классов @Entity
наряду со встроенной базой данных, которая применяется по умолчанию.
Примечание : Обычные @Компонентные
классы не загружаются в контексте приложения, созданном аннотацией @DataJpaTest
.
Он используется вместе с @RunWith(SpringRunner.class)
аннотация, которая указывает, какие средства будут использоваться отмеченным классом.
По умолчанию все транзакции JPA будут откатываться (вы можете изменить это поведение, применив либо @Откат(ложь)
или |/@Фиксация ):
@RunWith(SpringRunner.class) @DataJpaTest public class SomeJpaTest { // Rest of the code }
Это классический тест JPA, однако, если вы хотите использовать реальную базу данных вместо встроенной базы данных в памяти, вы можете просто добавить еще одну аннотацию, чтобы предотвратить такое поведение:
@RunWith(SpringRunner.class) @DataJpaTest @AutoConfigureTestDatabase(replace = Replace.NONE) public class SomeJpaTest { // Rest of the code }
@@Datamonitor
Очень похоже на аннотацию @DataJpaTest
, для выполнения классических тестов MongoDB мы применяем аннотацию @DataMongoTest
наряду с @RunWith(SpringRunner.class)
аннотация.
Имейте в виду, что эта аннотация используется, когда тест, к которому она применяется, проверяет только компоненты MongoDB и добавляет только @Document
классы в контекст приложения:
@RunWith(SpringRunner.class) @DataMongoTest public class SomeMongoTest { // Rest of the code }
Опять же, если вы хотите запустить это с реальной базой данных, а не со встроенной базой данных в памяти, предоставленной Mongo, вы можете исключить этот вариант:
@RunWith(SpringRunner.class) @DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class) public class SomeMongoTest { // Rest of the code }
@WebMvcTest
Опять же, очень похоже на @DataJpaTest
и @DataMongoTest
аннотации, для выполнения классических тестов Spring MVC мы применяем @WebMvcTest
аннотацию вместе с @RunWith(SpringRunner.class)
аннотация.
Имейте в виду, что эффекты этой аннотации применимы только к инфраструктуре MVC. Тем не менее, это не создает экземпляр всего контекста.
Аннотацию можно использовать для тестирования одного контроллера, передав ее в качестве атрибута, такого как @WebMvcTest(SomeController.class)
.
Для создания других необходимых зависимостей, таких как службы, мы обычно используем аннотацию @MockBean
. @WebMvcTest
настраивает MockMvc
, который можно использовать для простого и быстрого тестирования контроллеров MVC и создания экземпляров других сотрудников:
@RunWith(SpringRunner.class) @WebMvcTest(HomeController.class) public class ControllerTests { // Auto-configured to make mocking easier @Autowired private MockMvc mockMvc; @MockBean private SomeBean someBean; @Test public void someTest() { // Test logic } }
@@Mockbeat
При тестировании конкретных устройств, таких как, скажем, контроллер, мы хотим изолировать их как можно больше. Поскольку большинство компонентов приложения Spring зависят от множества других компонентов (зависимостей), крайне важно убедиться, что все эти компоненты можно тестировать по отдельности.
Чтобы успешно изолировать объекты, которые мы хотим протестировать, и при этом позволить приложению работать нормально, мы имитируем или моделируем зависимости. @MockBean
аннотация используется, когда мы хотим имитировать зависимость в приложении:
@RunWith(SpringRunner.class) @WebMvcTest(HomeController.class) public class ControllerTests { // Auto-configured to make mocking easier @Autowired private MockMvc mockMvc; @MockBean private SomeBean someBean; @Test public void someTest() { // Test logic } }
В этом примере зависимость SomeBean
имитирует реальную зависимость. Если компонент существует в контексте, макет заменяет его. Если он не существует, макет добавляется в контекст в виде компонента.
Примечание : Существует разница между аннотациями @Mock
и @MockBean
. Аннотация @Mock
взята из библиотеки Mockito и эквивалентна вызову метода Mockito.mock ()
. С другой стороны, @MockBean
является оболочкой библиотеки Spring аннотации @Mock
.
@AutoConfigureMockMvc
Как следует из названия, аннотация @AutoConfigureMockMvc
при применении к тестовому классу автоматически настраивает MockMvc
таким же образом @WebMvcTest
автоматически настраивает его.
@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class ControllerTests { @Autowired private MockMvc mockMvc; // Rest of the logic }
Если вы хотите сосредоточиться только на веб-слое, рассмотрите возможность использования вместо этого аннотации @WebMvcTest
.
@JsonTest
Многие приложения имеют дело с сериализацией JSON/десериализацией . Поэтому имеет смысл убедиться, что он работает правильно во время тестирования приложения. Используя аннотацию @JsonTest
, Spring автоматически настраивает поддерживаемый JSON-картограф (Jackson, Json или Jsonb).
Обычно он используется вместе с @RunWith(SpringRunner.class)
и используется для классических тестов JSON, сканируя @JsonComponent
s.
@RunWith(SpringRunner.class) @JsonTest public class JsonTests { @Test public void someJsonTest() { // Rest of the logic } }
@TestPropertySource
Аннотация @TestPropertySource
применяется к уровню класса и определяет расположение источников свойств, которые мы хотим использовать для теста.
Эти свойства сохраняются в виде набора @PropertySource
s в среде контекста приложения. Эти свойства имеют приоритет над свойствами системы или приложения.
По сути, когда мы хотим переопределить свойства системы/приложения конкретными свойствами для наших тестов, мы просто аннотируем тестовый класс:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = TestConfiguration.class) @TestPropertySource("classpath:applicationtest.properties") public class ApplicationTest { // Rest of the logic }
С другой стороны, вы можете указать встроенные свойства, а не весь файл свойств:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = TestConfiguration.class) @TestPropertySource(properties = {"sa.website_name = stackabuse", "sa.website_url = www.stackabuse.com"}) public class ApplicationTest { // Rest of the logic }
@Приурочено
Аннотация @Timed
определяет время в миллисекундах, в течение которого метод тестирования должен завершить выполнение, в противном случае он завершится неудачно:
@Timed(millis = 1000) public void testMethod() { // Some test logic }
Если выполнение теста займет больше секунды, он завершится неудачей. Это включает в себя все повторения метода, если присутствует аннотация @Repeat
.
@Повтор
Аннотация @Repeat
определяет, сколько раз должен быть повторен метод тестирования:
@Repeat(5) @Test public void testMethod() { // Some test logic }
Этот тест будет повторен пять раз.
Вывод
Фреймворк Spring-это мощный и надежный фреймворк, который действительно изменил игру, когда дело доходит до разработки веб-приложений. Среди всего, что он поддерживает, он предлагает отличную поддержку TDD для приложений Spring и позволяет разработчикам легко и быстро настраивать любые тесты.