1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/chanjarster-spring-test-examples

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
chapter_1_s3_spring_boot_testing.md 12 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 23:55 3b54fb2

Глава 1: Основные способы использования — инструменты тестирования Spring Boot

В предыдущей части мы рассмотрели, как использовать инструменты тестирования Spring для тестирования проектов Spring. Теперь мы рассмотрим, как использовать инструменты тестирования Spring Boot для тестирования проектов Spring Boot.

В проекте Spring Boot можно использовать как инструменты тестирования Spring Boot, так и инструменты тестирования Spring. В проектах Spring обычно используют инструменты тестирования Spring, хотя теоретически можно использовать и инструменты тестирования Spring Boot. Однако, поскольку инструменты тестирования Spring Boot могут привнести некоторые особенности Spring Boot в тестирование, что может вызвать странные проблемы, обычно не рекомендуется это делать.

Пример 1: прямое подключение Bean

Чтобы использовать инструменты тестирования Spring Boot, достаточно заменить @ContextConfiguration на @SpringBootTest. Исходный код см. в FooServiceImpltest:

@SpringBootTest(classes = FooServiceImpl.class)
public class FooServiceImplTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private FooService foo;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getCount(), 0);

    foo.plusCount();
    assertEquals(foo.getCount(), 1);
  }

}

Пример 2: использование встроенного @Configuration для подключения Bean

Исходный код см. в FooServiceImpltest:

@SpringBootTest
public class FooServiceImplTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private FooService foo;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getCount(), 0);

    foo.plusCount();
    assertEquals(foo.getCount(), 1);
  }

  @Configuration
  @Import(FooServiceImpl.class)
  static class Config {
  }

}

Пример 3: использование внешнего @Configuration для подключения Bean

Config:

@Configuration
@Import(FooServiceImpl.class)
public class Config {
}

FooServiceImpltest:

@SpringBootTest(classes = Config.class)
public class FooServiceImplTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private FooService foo;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getCount(), 0);

    foo.plusCount();
    assertEquals(foo.getCount(), 1);
  }

}

Этот пример похож на пример 2, но @Configuration вынесена наружу.

Пример 4: использование @SpringBootConfiguration

Использование @SpringBootTest аналогично использованию @ContextConfiguration. Согласно документации @SpringBootTest:

  1. Он пытается загрузить классы, определённые в @SpringBootTest (classes=...), если они заданы. Определение классов с аннотациями описано в ContextConfiguration.
  2. Если не задано @SpringBootTest (classes=...), то он ищет вложенный класс @Configuration текущего тестового класса.
  3. Если предыдущий шаг успешен, то он пытается найти @SpringBootConfiguration, ища его следующим образом:
    • Проверяет, является ли текущий тестовый класс @SpringBootConfiguration.
    • Ищет в пакете текущего тестового класса.

Поэтому мы можем использовать эту функцию для дальнейшего упрощения кода тестирования.

Config:

@SpringBootConfiguration
@Import(FooServiceImpl.class)
public class Config {
}

FooServiceImpltest:

@SpringBootTest
public class FooServiceImplTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private FooService foo;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getCount(), 0);

    foo.plusCount();
    assertEquals(foo.getCount(), 1);
  }

}

Пример 5: использование @ComponentScan для сканирования Bean

Во всех предыдущих примерах мы использовали @Import для загрузки Bean, хотя этот метод очень точный, он может быть громоздким в больших проектах.

Обычно в обычных проектах Spring Boot используется автоматическое сканирование для загрузки Bean, поэтому мы хотим, чтобы наш тестовый код также мог использовать автоматическое сканирование для загрузки Bean.

Config:

@SpringBootConfiguration
@ComponentScan(basePackages = "me.chanjar.basic.service")
public class Config {
}

FooServiceImpltest:

@SpringBootTest
public class FooServiceImplTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private FooService foo;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getCount(), 0);

    foo.plusCount();
    assertEquals(foo.getCount(), 1);
  }

}

Пример 6: использование @SpringBootApplication

Также можно использовать @SpringBootApplication в тестовом коде. У него есть несколько преимуществ:

  1. Это собственная конфигурация @SpringBootConfiguration.
  2. Предоставляет конфигурацию @ComponentScan, а также default excludeFilter, благодаря чему Spring при инициализации ApplicationContext исключает некоторые Bean и @Configuration.
  3. Включает EnableAutoConfiguration, что позволяет использовать Spring Boot для автоматической настройки необходимых внешних ресурсов, таких как базы данных и JMS, что полезно при интеграционном тестировании.

Config:

@SpringBootApplication(scanBasePackages = "me.chanjar.basic.service")
public class Config {
}

FooServiceImpltest:

@SpringBootTest
public class FooServiceImplTest extends
``` **Избегаем конфликта @SpringBootConfiguration**

Когда `@SpringBootTest` не определяет `(classes=...`, и не найден nested `@Configuration` class, будет предпринята попытка поиска `@SpringBootConfiguration`. Если найдено несколько таких классов, то будет выброшено исключение:

Caused by: java.lang.IllegalStateException: Found multiple @SpringBootConfiguration annotated classes [Generic bean: class [...]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [/Users/qianjia/workspace-os/spring-test-examples/basic/target/test-classes/me/chanjar/basic/springboot/ex7/FooServiceImplTest1.class], Generic bean: class [me.chanjar.basic.springboot.ex7.FooServiceImplTest2]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [...]]


Например, следующий код вызовет эту проблему:

```java
@SpringBootApplication(scanBasePackages = "me.chanjar.basic.service")
public class Config1 {
}

@SpringBootApplication(scanBasePackages = "me.chanjar.basic.service")
public class Config2 {
}

@SpringBootTest
public class FooServiceImplTest extends AbstractTestNGSpringContextTests {
  // ...
}

Чтобы решить эту проблему, можно избежать автоматического поиска @SpringBootConfiguration:

  1. Определить @SpringBootTest(classes=...)
  2. Предоставить nested @Configuration class

Лучшая практика

Кроме модульного тестирования (не требуется инициализация ApplicationContext), рекомендуется максимально согласовывать тестовую конфигурацию с производственной конфигурацией. Например, если в производственной конфигурации включена AutoConfiguration, то и в тестовой конфигурации она должна быть включена. Только так можно обнаружить проблемы в производственной среде в тестовом окружении и избежать некоторых странных проблем, вызванных различиями в конфигурации.

Между тестовыми кодами следует стараться использовать общую конфигурацию, что имеет три преимущества:

  1. Можно эффективно использовать механизм кэширования Spring TestContext Framework, ApplicationContext создаётся только один раз, а последующие тесты используют уже созданный, что ускоряет выполнение тестового кода.
  2. Когда в проекте много Bean, это может снизить сложность тестового кода, представьте, если бы каждый тестовый код имел свою собственную @Configuration или её вариант, это было бы очень сложно.

Справочные документы

  • Spring Framework Testing
  • Spring Boot Testing
  • Spring TestContext Framework

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/chanjarster-spring-test-examples.git
git@api.gitlife.ru:oschina-mirror/chanjarster-spring-test-examples.git
oschina-mirror
chanjarster-spring-test-examples
chanjarster-spring-test-examples
master