0


详细分析SpringBootTest中的测试类(附Demo)

目录

前言

书写测试类,一般只需要加入@Test即可,但是结合Springboot项目来整体测试对应需要怎么下手

详细的Java知识点推荐阅读:java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)

1. 基本知识

涉及测试类的基本注解分析如下:

一、

@SpringBootTest

:加载完整的Spring应用上下文
使用场景:需要测试整个Spring Boot应用时使用,确保所有的Bean都能被正确加载

@SpringBootTestpublicclassMyApplicationTests{// 测试方法}

二、

@RunWith(SpringRunner.class)

:指定测试运行器,这里使用SpringRunner来运行Spring Boot测试
使用场景:结合JUnit 4使用时指定测试运行器

@RunWith(SpringRunner.class)publicclassMyApplicationTests{// 测试方法}

三、

@Autowired

:自动注入Spring管理的Bean
使用场景:在测试类中需要注入服务、仓库等Bean时使用

@AutowiredprivateMyService myService;

四、

@Slf4j

:使用Lombok提供的日志记录功能
使用场景:需要在类中记录日志时使用

@Slf4jpublicclassMyApplicationTests{// 可以使用log.info(), log.debug()等记录日志}

五、

@Test

:标记一个方法为测试方法
使用场景:任何需要进行单元测试的方法都应使用该注解

@TestpublicvoidtestMethod(){// 测试逻辑}

常出现的情况有如下:

  1. 注入的Bean为null 使用@Autowired注入的Bean为null》》》》确保被注入的类被Spring管理(例如,使用@Service、@Component等注解),确保测试类使用@SpringBootTest注解以加载完整的Spring上下文
  2. 测试类无法加载上下文 测试类无法加载Spring上下文,抛出BeanCreationException等异常》》》》确保@SpringBootTest注解的classes属性指向正确的主应用程序类,例如AccidentApplication.class

2. Demo

结合实战中的Demo进行讲解

importcom.sinosoft.springbootplus.AccidentApplication;importlombok.extern.slf4j.Slf4j;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.test.context.junit4.SpringRunner;@SpringBootTest(classes =AccidentApplication.class)@Slf4jpublicclassTestClass{@AutowiredprivateXXXService xxxService;@TestpublicvoidtestDemo(){// 示例测试代码
        log.info("Starting testDemo");// 调用XXXService的某个方法,并进行断言String result = xxxService.someMethod();assertNotNull(result);
        log.info("testDemo completed");}}

其中的注意事项如下:

  1. 类路径:确保AccidentApplication类在你的类路径下,并且可以被正确加载
  2. Service注入:XXXService必须在Spring上下文中被定义为一个Bean,否则@Autowired注入会失败
  3. JUnit版本:确保项目使用JUnit 5(JUnit Jupiter)或者JUnit 4,不要混用 上面的代码中使用的是JUnit 5,如果你需要使用JUnit 4,请使用org.junit.Test和org.junit.runner.RunWith
  4. 日志使用:通过@Slf4j注解,可以在测试方法中方便地记录日志,这有助于调试

而且基本的项目结构如下:

src
├── main
│   └── java
│       └── com
│           └── manong
│               └── springbootplus
│                   ├── AccidentApplication.java
│                   └── service
│                       └── XXXService.java
└── test
    └── java
        └── com
            └── manong
                └── springbootplus
                    └── TestClass.java

3. 实战

3.1 项目测试

Demo与实战中大同小异,上述使用的是JUnit 5 ,下面使用一个JUnit 4进行演示

importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes =YudaoServerApplication.class)publicclass projectTest {@TestpublicvoidtestUsingTosDataSource(){}}

实际截图如下:

在这里插入图片描述

3.2 功能测试

实战中可能有多个模块,对应的配置需如下:

packagecn.example.module.dangerous.service.enterpriseregistry;importorg.junit.jupiter.api.Disabled;importorg.junit.jupiter.api.Test;importorg.springframework.boot.test.mock.mockito.MockBean;importjavax.annotation.Resource;importcn.example.framework.test.core.ut.BaseDbUnitTest;importcn.example.module.dangerous.controller.admin.enterpriseregistry.vo.*;importcn.example.module.dangerous.dal.dataobject.enterpriseregistry.EnterpriseRegistryDO;importcn.example.module.dangerous.dal.mysql.enterpriseregistry.EnterpriseRegistryMapper;importcn.example.framework.common.pojo.PageResult;importjavax.annotation.Resource;importorg.springframework.context.annotation.Import;importjava.util.*;importjava.time.LocalDateTime;importstaticcn.hutool.core.util.RandomUtil.*;importstaticcn.example.module.dangerous.enums.ErrorCodeConstants.*;importstaticcn.example.framework.test.core.util.AssertUtils.*;importstaticcn.example.framework.test.core.util.RandomUtils.*;importstaticcn.example.framework.common.util.date.LocalDateTimeUtils.*;importstaticcn.example.framework.common.util.object.ObjectUtils.*;importstaticcn.example.framework.common.util.date.DateUtils.*;importstaticorg.junit.jupiter.api.Assertions.*;importstaticorg.mockito.Mockito.*;/**
 * {@link EnterpriseRegistryServiceImpl} 的单元测试类
 *
 * @author 管理员
 */@Import(EnterpriseRegistryServiceImpl.class)publicclassEnterpriseRegistryServiceImplTestextendsBaseDbUnitTest{@ResourceprivateEnterpriseRegistryServiceImpl enterpriseRegistryService;@ResourceprivateEnterpriseRegistryMapper enterpriseRegistryMapper;@TestpublicvoidtestCreateEnterpriseRegistry_success(){// 准备参数EnterpriseRegistrySaveReqVO createReqVO =randomPojo(EnterpriseRegistrySaveReqVO.class).setId(null);// 调用Long enterpriseRegistryId = enterpriseRegistryService.createEnterpriseRegistry(createReqVO);// 断言assertNotNull(enterpriseRegistryId);// 校验记录的属性是否正确EnterpriseRegistryDO enterpriseRegistry = enterpriseRegistryMapper.selectById(enterpriseRegistryId);assertPojoEquals(createReqVO, enterpriseRegistry,"id");}@TestpublicvoidtestUpdateEnterpriseRegistry_success(){// mock 数据EnterpriseRegistryDO dbEnterpriseRegistry =randomPojo(EnterpriseRegistryDO.class);
        enterpriseRegistryMapper.insert(dbEnterpriseRegistry);// @Sql: 先插入出一条存在的数据// 准备参数EnterpriseRegistrySaveReqVO updateReqVO =randomPojo(EnterpriseRegistrySaveReqVO.class, o ->{
            o.setId(dbEnterpriseRegistry.getId());// 设置更新的 ID});// 调用
        enterpriseRegistryService.updateEnterpriseRegistry(updateReqVO);// 校验是否更新正确EnterpriseRegistryDO enterpriseRegistry = enterpriseRegistryMapper.selectById(updateReqVO.getId());// 获取最新的assertPojoEquals(updateReqVO, enterpriseRegistry);}@TestpublicvoidtestUpdateEnterpriseRegistry_notExists(){// 准备参数EnterpriseRegistrySaveReqVO updateReqVO =randomPojo(EnterpriseRegistrySaveReqVO.class);// 调用, 并断言异常assertServiceException(()-> enterpriseRegistryService.updateEnterpriseRegistry(updateReqVO),ENTERPRISE_REGISTRY_NOT_EXISTS);}@TestpublicvoidtestDeleteEnterpriseRegistry_success(){// mock 数据EnterpriseRegistryDO dbEnterpriseRegistry =randomPojo(EnterpriseRegistryDO.class);
        enterpriseRegistryMapper.insert(dbEnterpriseRegistry);// @Sql: 先插入出一条存在的数据// 准备参数Long id = dbEnterpriseRegistry.getId();// 调用
        enterpriseRegistryService.deleteEnterpriseRegistry(id);// 校验数据不存在了assertNull(enterpriseRegistryMapper.selectById(id));}@TestpublicvoidtestDeleteEnterpriseRegistry_notExists(){// 准备参数Long id =randomLongId();// 调用, 并断言异常assertServiceException(()-> enterpriseRegistryService.deleteEnterpriseRegistry(id),ENTERPRISE_REGISTRY_NOT_EXISTS);}@Test@Disabled// TODO 请修改 null 为需要的值,然后删除 @Disabled 注解publicvoidtestGetEnterpriseRegistryPage(){// mock 数据EnterpriseRegistryDO dbEnterpriseRegistry =randomPojo(EnterpriseRegistryDO.class, o ->{// 等会查询到
            o.setEnterpriseName(null);
            o.setCreditCode(null);
            o.setRegistrant(null);
            o.setCreateTime(null);
            o.setEnterpriseCode(null);
            o.setContactNumber(null);});
        enterpriseRegistryMapper.insert(dbEnterpriseRegistry);// 测试 enterpriseName 不匹配
        enterpriseRegistryMapper.insert(cloneIgnoreId(dbEnterpriseRegistry, o -> o.setEnterpriseName(null)));// 测试 creditCode 不匹配
        enterpriseRegistryMapper.insert(cloneIgnoreId(dbEnterpriseRegistry, o -> o.setCreditCode(null)));// 测试 registrant 不匹配
        enterpriseRegistryMapper.insert(cloneIgnoreId(dbEnterpriseRegistry, o -> o.setRegistrant(null)));// 测试 createTime 不匹配
        enterpriseRegistryMapper.insert(cloneIgnoreId(dbEnterpriseRegistry, o -> o.setCreateTime(null)));// 测试 enterpriseCode 不匹配
        enterpriseRegistryMapper.insert(cloneIgnoreId(dbEnterpriseRegistry, o -> o.setEnterpriseCode(null)));// 测试 contactNumber 不匹配
        enterpriseRegistryMapper.insert(cloneIgnoreId(dbEnterpriseRegistry, o -> o.setContactNumber(null)));// 准备参数EnterpriseRegistryPageReqVO reqVO =newEnterpriseRegistryPageReqVO();
        reqVO.setEnterpriseName(null);
        reqVO.setCreditCode(null);
        reqVO.setRegistrant(null);
        reqVO.setCreateTime(buildBetweenTime(2023,2,1,2023,2,28));
        reqVO.setEnterpriseCode(null);
        reqVO.setContactNumber(null);// 调用PageResult<EnterpriseRegistryDO> pageResult = enterpriseRegistryService.getEnterpriseRegistryPage(reqVO);// 断言assertEquals(1, pageResult.getTotal());assertEquals(1, pageResult.getList().size());assertPojoEquals(dbEnterpriseRegistry, pageResult.getList().get(0));}}

本文转载自: https://blog.csdn.net/weixin_47872288/article/details/139841764
版权归原作者 码农研究僧 所有, 如有侵权,请联系我们删除。

“详细分析SpringBootTest中的测试类(附Demo)”的评论:

还没有评论