xxcc140 / 编程 / 从零开始 -Spring Boot 2单元测试与集成测...

分享

   

从零开始 -Spring Boot 2单元测试与集成测试知识点全了-知识铺

2019-09-23  xxcc140

知识铺: 致力于打造轻知识点,持续更新每次的知识点较少,阅读不累。不占太多时间,不停地来唤醒你记忆深处的知识点。

从零开始 -Spring Boot 2单元测试与集成测试知识点全了-知识铺

一.单元测试与集成测试

学习在Spring Boot应用程序中编写单元测试和集成测试。了解单元测试和集成测试之间的区别,以及支持此类测试的注解。

1.1 单元测试:

通常,任何软件应用程序都分为不同的模块和组件。单独测试一个这样的组件时,称为单元测试。编写该代码是为了验证一小段代码是否正在执行预期的操作。

单元测试不能验证应用程序代码是否正确地与外部依赖项一起工作。它专注于单个组件并模拟与该组件交互的所有依赖项。

1.2 集成测试:

一旦开发并集成了不同的模块,便会执行集成测试。其主要目的是发现不同模块相互交互以端对端处理用户请求时的问题。

集成测试可以根据测试内容将整个应用程序进行集成测试,也可以仅将某些组件进行集成测试。他们可能需要为数据库实例和分配资源。尽管也可以模拟这些交互以提高测试性能。

就典型的Spring boot CRUD应用,可以编写单元测试来分别测试REST控制器,DAO层等。甚至不需要嵌入式服务器。

在集成测试中,将测试从控制器到持久层的完整请求处理。应用程序嵌入式服务器中运行,以创建应用程序上下文和所有bean。这些bean中的某些可能会被覆盖以模拟某些行为。

二、依赖关系

2.1 Junit 4测试(默认)

要在Spring Boot应用程序中编写测试,最好的方法引入测试包: spring-boot-starter-test。它把Junit 4依赖项带到具有测试范围的应用程序中。

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

2.2。Junit 5测试

Spring Boot也支持Junit 5测试。要使用Junit 5,请包括它的依赖项,并从spring-boot-starter-test中排除Junit 4 。

编写集成测试时,嵌入式数据库依赖关系非常方便。

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<!-- exclude junit 4 -->

<exclusions>

<exclusion>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

</exclusion>

</exclusions>

</dependency>

<!-- junit 5 -->

<dependency>

<groupId>org.junit.jupiter</groupId>

<artifactId>junit-jupiter-api</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.junit.jupiter</groupId>

<artifactId>junit-jupiter-engine</artifactId>

<scope>test</scope>

</dependency>

<dependency>

<groupId>com.h2database</groupId>

<artifactId>h2</artifactId>

<scope>test</scope>

<version>1.4.194</version>

</dependency>

三.启动测试

用Spring Boot编写的测试可以多种方式运行。让来看看几种最常见的方式。

3.1。@RunWith(SpringRunner.class)– [Junit 4]

默认情况下,编写的测试是在Junit 4中进行的。要运行此类测试,可以在类级别使用带有批注的SpringRunner类(扩展SpringJUnit4ClassRunner)@RunWith。

@RunWith(SpringRunner.class)

@WebFluxTest(controllers = EmployeeController.class)

public class EmployeeRestControllerTest {

//tests

}

3.2。@RunWith(MockitoJUnitRunner.class)– [Junit 4 with Mockito]

它@Mock使用MockitoJUnitRunner测试首选对象。它初始化带有Mock注解的模拟,因此MockitoAnnotations.initMocks(Object)不需要显式使用。在每种测试方法之前都要初始化模拟。

@RunWith(MockitoJUnitRunner.class)

public class EmployeeRestControllerTest

{

@Mock

private Repository repository;

}

3.3。@ExtendWith(SpringExtension.class)– [Junit 5]

SpringExtension将Spring TestContext Framework集成到JUnit 5的Jupiter编程模型中。

//@ExtendWith(SpringExtension.class)

// included in @WebFluxTest

@WebFluxTest(controllers = EmployeeController.class)

@Import(EmployeeService.class)

public class EmployeeControllerTest

{

//

}

3.4。@ExtendWith(MockitoExtension.class)– [Junit 5]

MockitoExtension初始化模拟并处理严格的存根。等同于MockitoJUnitRunner。

大多数测试注解都包含此注解,因此无需明确包含它。

@ExtendWith(MockitoExtension.class)

public class EmployeeControllerTest

{

//

}

四、 Spring Boot 测试注解

Spring Boot提供了各种注解,以启用仅与应用程序的某些部分相关的测试基础结构。它还提供了注解,这些注解也有助于集成测试。

4.1。@SpringBootTest

此批注有助于编写集成测试。它启动嵌入式服务器并完全初始化应用程序上下文。可以使用@Autowired批注将依赖项注入测试类中。

还可以使用嵌套的@Configuration类或显式的@TestConfiguration类提供特定于测试的bean装配。

它还为不同的web环境模式提供特定环境支持,并在定义的或随机的端口上侦听正在运行的Web服务器。它还注册了TestRestTemplate和/或WebTestClient的bean,用于Web测试。

@SpringBootTest(classes = SpringBootDemoApplication.class,

webEnvironment = WebEnvironment.RANDOM_PORT)

public class EmployeeControllerIntegrationTests

{

@LocalServerPort

private int port;

@Autowired

private TestRestTemplate restTemplate;

//tests

}

4.2。@WebMvcTest

该注解用于Spring MVC测试。它禁用完全自动装配,而是仅应用与MVC测试相关的装配。

它还会自动装配MockMvc实例。通过将其目标类.class作为注入属性,只能初始化一个Web控制器。

@WebMvcTest(EmployeeRESTController.class)

public class TestEmployeeRESTController {

@Autowired

private MockMvc mvc;

//

}

4.3。@WebFluxTest

此注解将禁用完全自动装配,而仅应用与WebFlux测试相关的装配。默认情况下,用@WebFluxTest注解的测试还将自动装配WebTestClient。

通常,@ WebFluxTest与@MockBean结合使用,或@Import创建控制器bean所需的任何协作者。

@WebFluxTest(controllers = EmployeeController.class)

@Import(EmployeeService.class)

public class EmployeeControllerTest

{

@MockBean

EmployeeRepository repository;

@Autowired

private WebTestClient webClient;

//tests

}

4.4。其他常用注解

  • @JdbcTest – 当测试仅关注基于jdbc的组件时,可用于典型的jdbc测试。它禁用完全自动装配,而是仅应用与jdbc测试相关的装配。

  • 默认情况下,用@JdbcTest注解的测试是事务性的,并在每个测试结束时回滚。注解装配了一个内存嵌入式数据库和JdbcTemplate。

  • @JooqTest –当测试仅针对基于jOOQ的组件时可以使用。注意,默认情况下,以@JooqTest注解的测试使用应用程序装配的数据库。若要使用嵌入式内存数据库,可以使用@AutoConfigureTestDatabase批注覆盖这些设置。

  • @JsonTest –当测试仅关注JSON序列化时使用。它初始化@JsonComponent,JacksonTester,JsonbTester和GsonTester领域。

  • @DataJpaTest –可用于测试JPA应用程序。默认情况下,它将扫描@Entity类并装配Spring Data JPA存储库。如果在类路径上有嵌入式数据库,它也将装配一个。

  • 默认情况下,数据JPA测试是事务性的,并在每次测试结束时回滚。

  • 数据JPA测试也可以注入TestEntityManager的bean,它提供了EntityManager专门为测试设计的标准JPA的替代方案。

  • @DataMongoTest –用于测试MongoDB应用程序。默认情况下,它装配内存嵌入式MongoDB(如果有),装配MongoTemplate,扫描@Document类,并装配Spring Data MongoDB存储库。

  • @DataRedisTest –用于测试Redis应用程序。默认情况下,它会扫描@RedisHash类并装配Spring Data Redis存储库。

  • @DataLdapTest –用于测试LDAP应用程序。默认情况下,它装配内存嵌入式LDAP(如果可用),装配LdapTemplate,扫描@Entry类,并装配Spring Data LDAP存储库。

  • @RestClientTest –用于测试REST客户端。默认情况下,它会自动装配Jackson,GSON和Jsonb支持,装配RestTemplateBuilder,并添加对的支持MockRestServiceServer。

五.测试装配

@TestConfiguration是一种特殊的形式@Configuration,可用于定义其他bean或测试的自定义项。

在Spring启动中,@TestConfiguration将不会通过组件扫描来拾取在顶级类中装配有注解的任何bean 。必须使用包含测试用例的类显式注册@TestConfiguration类。

最好的是,这些测试装配不会自动成为应用程序主装配的一部分。仅可使用以下两种方式之一按需提供这些附加测试装配,即:

5.1。@导入注解

它称为将一个或多个装配类导入应用程序上下文或Spring测试上下文中。

@Import(MyTestConfiguration.class)

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

public class SpringBootDemoApplicationTests

{

@LocalServerPort

int randomServerPort;

@Autowired

DataSource datasource;

//tests

}

5.2。静态嵌套类

可以在测试类内部的嵌套类中定义测试装配。嵌套类可以使用@Configuration或@TestConfiguration批注进行注解。

如果是嵌套@Configuration类,则将使用给定的装配“代替”应用程序的主要装配。

嵌套@TestConfiguration类用于“附加”应用程序的主要装配。

@Import(MyTestConfiguration.class)

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

public class SpringBootDemoApplicationTests

{

@LocalServerPort

int randomServerPort;

@Autowired

DataSource datasource;

//tests

}

六.模拟 mock测试数据

对于使用或不使用Mockito的依赖关系,Spring Boot都提供了出色的支持。

6.1。与Mockito结合 – @Mock

@Mock用于模拟创建。它使测试类更具可读性。在测试类中,MockitoAnnotations.initMocks(testClass)必须至少使用一次以处理模仿注解。

请注意,如果正在使用,RunWith(MockitoJUnitRunner.class)则无需显式使用MockitoAnnotations.initMocks()。在每种测试方法之前都要初始化模拟。

用于@Mock不需要Spring文本上下文的单元测试中。

6.2。没有Mockito – @MockBean

@MockBean批注用于将模拟添加到Spring ApplicationContext。它允许模拟类或接口,并记录和验证其行为。

有趣的是,上下文中定义的任何相同类型的现有bean都将被该模拟代替。如果没有定义现有的bean,将添加一个新的bean。

@MockBean与mockito的相似,@Mock但具有Spring支持。通常会使用@MockBean连同任一@WebMvcTest或@WebFluxTest注解。这些注解适用于Web测试片,并且仅限于单个控制器。

在给定的示例中,在模拟EmployeeRepository的bean中。这样,将调用所有应用程序代码,但是这也只是模拟所有与数据库交互方式。

@WebFluxTest(controllers = EmployeeController.class)

@Import(EmployeeService.class)

public class EmployeeControllerTest

{

@MockBean

EmployeeRepository repository;

@Autowired

private WebTestClient webClient;

//tests

}

七.结论

Spring Boot为应用程序及其各种模块的单元测试和集成测试提供了出色的支持。将非常小心地通过使用注解来使用所提供的支持。

使用@SpringBootTest注解进行集成测试,而使用其他自动装配批注进行特定组件的单元测试。

模拟特定行为是非常普遍的要求,为此,可以使用模拟的@Mock或Spring的@MockBean注解。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>