SpringBoot: запуск юнит-теста Junit с минимальной конфигурацией - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть проект Springboot, в котором я нашел способ создания и запуска простого Junit тестового примера, который просматривает хранилище и извлекает некоторый атрибут данных для данной сущности. Результат выполнения Junit - pass, поэтому никаких проблем с этим нет.

Но дело в том, что я видел множество примеров, где учебники показывают Springboot проектов, где они могут просто запускать Junit тесты, используя только @Runwith или @SpringBootTest для своих Speci c тестовые классы.

В моем случае мне нужно добавить 3 аннотации @SpringBootTest, @RunWith, а также @ContextConfiguation(with parameters), пока я не смогу запустить тестовый сценарий.

Итак, мой вопрос: как я смогу выполнить его как можно более минималистично c (в некоторых упражнениях, которые я видел, есть только одна аннотация для тестового класса прыгуна)

My Springboot тестовый класс выглядит следующим образом:

Снимок экрана моего класса Junit

и структура моего каталога выглядит следующим образом:

Снимок экрана Моя структура каталогов проекта

Мой application.properties выглядит следующим образом:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.show-sql=true
spring.datasource.url=jdbc:postgresql://localhost:5432/erfan
spring.datasource.username=erfan
spring.datasource.password=

#Some additional properties is trying to be set by Spring framework so this must be set
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true


#spring.datasource.initialization-mode=always
#spring.datasource.initialize=true
#spring.datasource.schema=classpath:/schema.sql
#spring.datasource.continue-on-error=true 

#HikariCP is a ConnectionPool manager, related to DB stuff



#Below is the property key you need to set to * as value to expose all kind of monitoring related information
#about your web application 

#management.endpoints.web.exposure.include=*

И мой файл pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>
    <groupId>com.sample</groupId>
    <artifactId>postgres</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>postgres</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>



    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>



        </plugins>






    </build>
</project>

Так что я скучаю как что-то в моем файле application.properties? Что-то, что я должен включить, чтобы иметь возможность удалить "шаблонную" аннотацию в моем тестовом классе?

Ответы [ 3 ]

0 голосов
/ 07 февраля 2020

Я настоятельно рекомендую не использовать кучу весенних аннотаций при юнит-тестах. Модульные тесты должны проверять только один кусок кода и не связаны с внешними или другими уровнями, поэтому должно быть достаточно Mockito.

Пример:

@RunWith(MockitoJUnitRunner.class)
public class FooTest {
   @InjectMocks
   private FooService service;

   @Mock
   private FooRepository repository;

   @Test
   public void whenHappyPath_shouldReturnTrue(){
      doReturn(Optional.empty()).when(repository).findById(anyLong());
      assertTrue(service.isFoo(1L));
   }
}

Вы запрещаете вашему модульному тесту достигните уровня репозитория, так что вам не нужно создавать контекст со встроенной БД или чем-то другим.

Если вы используете для интеграционных тестов, то он другой, и вам потребуются разные стратегии. Для этого я бы рекомендовал использовать встроенные БД в тестах (что делается по умолчанию, если у вас есть зависимость h2):

<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <scope>runtime</scope>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
</dependency>

, а также использовать integration или test пружинный профиль:

@ActiveProfile("test") // or integration, you choose
public class FooIntegrationTest{
   ...
}

или заставить другой файл конфигурации указывать на другую конфигурацию

@TestPropertySource(properties = { "spring.config.location=classpath:application-test.yml" })

application-test.properties

spring.datasource.url=jdbc:h2:mem:test
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
0 голосов
/ 07 февраля 2020

Erfan, это полностью зависит от вашего сценария тестирования.

Первый сценарий: полный тест (интеграционный тест)

Если вы хотите протестировать все свое приложение Как и при тестировании уровня Service, слоя Repository и уровня Controller, вам нужен реальный контекст Spring, поэтому вы должны использовать все @SpringBootTest и @RunWith и ... для инициализации контекста Spring для тестирования целых слоев. (Это называется интеграционным тестом)

Модульный тест и интеграционный тест: в чем разница

как использовать- java -интеграция-тестирование

Второй сценарий: модульное тестирование

Если вы хотите просто протестировать часть своего кода, точно так же, как вы хотите протестировать только служебный слой, а другие слои (например, хранилище) не важно в вашем сценарии, в этой ситуации вы должны использовать некоторые новые фреймворки, такие как Mockito, чтобы высмеивать фрагменты, которые вы не хотите тестировать, в этом сценарии ios вам не нужен ** весенний контекст инициализация **, поэтому вам не нужно использовать @SpringBootTest или другие аннотации.

Образец мокито

Таким образом, в зависимости от вашего сценария вы можете использовать эти аннотации.


Я настоятельно рекомендую вам прочитать ссылку ниже для получения дополнительной информации о передовых методах тестирования в java.

Современных передовых методах тестирования в Java

0 голосов
/ 07 февраля 2020

Зависит от того, что вы пытаетесь сделать. В основном у Spring есть пользовательские аннотации, которые настраивают контекст Spring для включения только соответствующих bean-компонентов. Это так называемые test slices.

Но есть несколько «правил», которым я всегда стараюсь следовать:

  • Избегайте @SpringBootTest, если вы не проводите интеграционное тестирование, или вручную установить, какие классы использовать @SpringBootTest(classes = {MyService1.class, MyService2.class}
  • Если вы тестируете Spring jpa, вы можете использовать аннотацию @DataJpaTest, например здесь
  • Если вы ' Для повторного тестирования контроллеров вы можете использовать @WebMvcTest, например здесь
  • Если вы тестируете другие сервисы, вы всегда можете использовать @ContextConfiguration для соответствующей настройки контекста пружины.

Так, например, для вашего теста я бы написал его одним из двух способов:

@RunWith(SpringRunner.class)
@DataJpaTest
@Import(AnotherConfig.class)
class MyTest {
   // test stuff here
}
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {AnotherConfig.class})
// NOTE, if you have a JpaConfig class where you @EnableJpaRepositories
// you can instead add this config class to the @ContextConfiguration classes
@EnableJpaRepositories
class MyTest {
   // test stuff here
}

В принципе, не беспокойтесь о том, сколько у вас аннотаций поверх ваш тест, но беспокоитесь о том, какие бины / сервисы подключаются автоматически. Например, @SpringBootTest - это отдельная аннотация, но она автоматически связывает все компоненты в контексте весны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...