Рубрики
Без рубрики

Весенние аннотации: Тестирование

Автор оригинала: 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 и позволяет разработчикам легко и быстро настраивать любые тесты.