当前位置: 首页 > 工具软件 > HTML5test > 使用案例 >

spring-boot-starter-test---测试组件

方英耀
2023-12-01

SpringBootTest单元测试组件

一、SpringbootTest 使用Junit4开发

1、添加依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
2、单元测试类
  • @RunWith(SpringRunner.class)
  • @SpringBootTest(classes = {VipThinkICodeCourseApplication.class})
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    public void testAddUser() {
        User user = new User();
        user.setName("john");
        user.setAddress("earth");
        userService.add(user);
    }

}
3、JUnit4相关注解
  • @BeforeClass:针对所有测试,只执行一次,且必须为static void

  • @Before:初始化方法,执行当前测试类的每个测试方法前执行。

  • @Test:测试方法,在这里可以测试期望异常和超时时间

    • timeout = 2000 测试超时
    • expected=Exception.Class 测试抛出的异常
  • @After:释放资源,执行当前测试类的每个测试方法后执行

  • @AfterClass:针对所有测试,只执行一次,且必须为static void

  • @Ignore:忽略的测试方法(只在测试类的时候生效,单独执行该测试方法无效)

4、Assert断言相关API

二、SpringbootTest 使用Junit5开发

1、添加依赖

移除掉Junit4的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.3.2-RELEASE</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>
2、单元测试类
  • @ExtendWith(SpringExtension.class)指定测试的引擎类
  • @TestMethodOrder(MethodOrderer.Alphanumeric.class)指定测试的顺序
  • @SpringBootTest 指定测试的启动类
    • args = “–app.test=one” 指定参数
    • classes 指定启动类,可以是多个
    • value 指定配置属性
    • properties 指定配置属性,和value相同
    • webEnvironment 指定web环境,
      • MOCK 此值为默认值,该类型提供一个mock环境,此时内嵌的服务(servlet容器)并没有真正启动,也不会监听web端口
      • RANDOM_PORT 启动一个真实的web服务,监听一个随机端口
      • DEFINED_PORT 启动一个真实的web服务,监听一个定义好的端口(从配置中读取)。
      • NONE 启动一个非web的ApplicationContext,既不提供mock环境,也不提供真是的web服务
  • @Test 指定测试方法
@Slf4j
@ExtendWith(SpringExtension.class)
@TestMethodOrder(MethodOrderer.Alphanumeric.class)
@SpringBootTest(classes = {VipThinkICodeCourseApplication.class})
public class LearnerCourseServiceTest {

    @Autowired
    private LearnerCourseService learnerCourseService;

    @Test
    public void getLearnerCourse() {
        try {
            List<CouseSchedulVo> couseSchedulers = learnerCourseService.getCouseSchedulers(219772514);
            System.out.println(JSONUtil.toJsonPrettyStr(couseSchedulers));
        } catch (Exception e) {
            log.error("单元测试出现异常!", e);
            Assertions.assertTrue(true);
        }
    }
}
3、Junit5相关注解
(1)执行顺序
  • @BeforeEach:在每个单元测试方法执行前都执行一遍
  • @BeforeAll:在每个单元测试方法执行前执行一遍(只执行一次)
  • @AfterAll 表示在所有单元测试之后执行
  • @AfterEach 表示在每个单元测试之后执
(2)其他特性
  • @DisplayName(“商品入库测试”):用于指定单元测试的名称
  • @Disabled:当前单元测试置为无效,即单元测试时跳过该测试
  • @RepeatedTest(n):重复性测试,即执行n次
  • @ParameterizedTest:参数化测试,
  • @ValueSource(ints = {1, 2, 3}):参数化测试提供数据
  • @Timeout(value = 3,unit = TimeUnit.SECONDS)
4、Assertions断言
//嵌套单元测试
@SpringBootTest
@AutoConfigureMockMvc
@DisplayName("Junit5单元测试")
public class MockTest {
    //....
    @Nested
    @DisplayName("内嵌订单测试")
    class OrderTestClas {
        @Test
        @DisplayName("取消订单")
        void cancelOrder() {
            int status = -1;
            System.out.println("取消订单成功,订单状态为:"+status);
        }
    }
}
//参数化测试
	@ParameterizedTest
    @ValueSource(ints = {1, 2, 3})
    @DisplayName("参数化测试")
    void paramTest(int a) {
        assertTrue(a > 0 && a < 4);
    }
//重复测试
 	@RepeatedTest(3)
    @DisplayName("重复测试")
    void repeatedTest() {
        System.out.println("调用");
    }
//组合测试
	@Test
    @DisplayName("测试组合断言")
    void testAll() {
        assertAll("测试item商品下单",
                () -> {
                    //模拟用户余额扣减
                    assertTrue(1 < 2, "余额不足");
                },
                () -> {
                    //模拟item数据库扣减库存
                    assertTrue(3 < 4);
                },
                () -> {
                    //模拟交易流水落库
                    assertNotNull(new Object());
                }
        );
    }
//测试超时
	@Test
	@Timeout(value = 3,unit = TimeUnit.SECONDS)
	@DisplayName("超时测试")
 	void timeoutTest() {
        System.out.println("超时测试");
    }

三、高级特性

1、切片测试
@RunWith(SpringRunner.class)
@WebMvcTest(IndexController.class)
public class SpringBootTest {
    @Autowired
    private MockMvc mvc;
    
    @Test
    public void testExample() throws Exception {
        //groupManager访问路径
        //param传入参数
        MvcResult result=mvc.perform(MockMvcRequestBuilders
            .post("/groupManager")
            .param("pageNum","1")
            .param("pageSize","10"))
            .andReturn();
        MockHttpServletResponse response = result.getResponse();
        String content = response.getContentAsString();
        List<JtInfoDto> jtInfoDtoList = GsonUtils.toObjects(content,
                         new TypeToken<List<JtInfoDto>>() {}.getType());
        for(JtInfoDto infoDto : jtInfoDtoList){
            System.out.println(infoDto.getJtCode());
        }

    }
}
2、注解的使用
(1)配置类型
  • @TestComponent:该注解是另一种@Component,在语义上用来指定某个Bean是专门用于测试的。该注解适用于测试代码和正式混合在一起时,不加载被该注解描述的Bean,使用不多。
  • @TestConfiguration:该注解是另一种@TestComponent,它用于补充额外的Bean或覆盖已存在的Bean。在不修改正式代码的前提下,使配置更加灵活。
  • @TypeExcludeFilters:用来排除@TestConfiguration和@TestComponent。适用于测试代码和正式代码混合的场景,使用不多。
  • @OverrideAutoConfiguration:可用于覆盖@EnableAutoConfiguration,与ImportAutoConfiguration结合使用,以限制所加载的自动配置类。在不修改正式代码的前提下,提供了修改配置自动配置类的能力。
  • @PropertyMapping:定义@AutoConfigure*注解中用到的变量名称,例如在@AutoConfigureMockMvc中定义名为spring.test.mockmvc.webclient.enabled的变量。一般不使用。
  • 使用@SpringBootApplication启动测试或者生产代码,被@TestComponent描述的Bean会自动被排除掉。如果不是则需要向@SpringBootApplication添加TypeExcludeFilter。
(2)mock类型的注解
  • @MockBean:用于mock指定的class或被注解的属性。
  • @MockBeans:使@MockBean支持在同一类型或属性上多次出现。
  • @SpyBean:用于spy指定的class或被注解的属性。
  • @SpyBeans:使@SpyBean支持在同一类型或属性上多次出现
(3)自动配置类注解
  • @AutoConfigureJdbc 自动配置JDBC
  • @AutoConfigureCache 自动配置缓存
  • @AutoConfigureDataLdap 自动配置LDAP
  • @AutoConfigureJson 自动配置JSON
  • @AutoConfigureJsonTesters 自动配置JsonTester
  • @AutoConfigureDataJpa 自动配置JPA
  • @AutoConfigureTestEntityManager 自动配置TestEntityManager
  • @AutoConfigureRestDocs 自动配置Rest Docs
  • @AutoConfigureMockRestServiceServer 自动配置 MockRestServiceServer
  • @AutoConfigureWebClient 自动配置 WebClient
  • @AutoConfigureWebFlux 自动配置 WebFlux
  • @AutoConfigureWebTestClient 自动配置 WebTestClient
  • @AutoConfigureMockMvc 自动配置 MockMvc
  • @AutoConfigureWebMvc 自动配置WebMvc
  • @AutoConfigureDataNeo4j 自动配置 Neo4j
  • @AutoConfigureDataRedis 自动配置 Redis
  • @AutoConfigureJooq 自动配置 Jooq
  • @AutoConfigureTestDatabase 自动配置Test Database,可以使用内存数据库
(4)启动类注解

​ @SpringBootTest之外的注解都是用来进行切面测试的,他们会默认导入一些自动配。

  • @SpringBootTest 自动侦测并加载@SpringBootApplication或@SpringBootConfiguration中的配置,默认web环境为MOCK,不监听任务端口
  • @DataRedisTest 测试对Redis操作,自动扫描被@RedisHash描述的类,并配置Spring Data Redis的库
  • @DataJpaTest 测试基于JPA的数据库操作,同时提供了TestEntityManager替代JPA的EntityManager
  • @DataJdbcTest 测试基于Spring Data JDBC的数据库操作
  • @JsonTest 测试JSON的序列化和反序列化
  • @WebMvcTest 测试Spring MVC中的controllers
  • @WebFluxTest 测试Spring WebFlux中的controllers
  • @RestClientTest 测试对REST客户端的操作
  • @DataLdapTest 测试对LDAP的操作
  • @DataMongoTest 测试对MongoDB的操作
  • @DataNeo4jTest 测试对Neo4j的操作

四、控制层接口测试

@Slf4j
@SpringBootTest
@AutoConfigureMockMvc  //自动配置 MockMvc
class DemoControllerTest1 {

    @Autowired
    private MockMvc mock;
	//测试get提交
    @Test
    void findById() throws Exception {
        MvcResult mvcResult = mock.perform(MockMvcRequestBuilders.get("/demo/find/123").characterEncoding("UTF-8"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value("S0000")) //比较json结果值
                .andReturn();
        MockHttpServletResponse response = mvcResult.getResponse();
        response.setCharacterEncoding("UTF-8");
        String content = response.getContentAsString();
        log.info("findById Result: {}", content);
    }
	//测试post提交
    @Test
    void save() throws Exception {
        MvcResult mvcResult = mock.perform(
                MockMvcRequestBuilders.post("/demo/save")
                        .contentType(MediaType.APPLICATION_JSON_VALUE)
                        .characterEncoding("UTF-8")
                        .content(JSONObject.toJSONString(new DemoVo("Hello World")))
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value("S0000")) //比较json结果值
                .andReturn();
        MockHttpServletResponse response = mvcResult.getResponse();
        response.setCharacterEncoding("UTF-8");
        String content = response.getContentAsString();
        log.info("save Result: {}", content);
    }

   
}

参考:https://www.cnblogs.com/myitnews/p/12330297.html

https://www.cnblogs.com/haixiang/p/13812363.html

 类似资料: