Spring单元测试+Mockito

一,背景

单元测试基本上是开发逃不过的一个工作内容,虽然往往因为过于无聊,或者过于麻烦,而停止于项目的迭代之中,不了了之了。其实不是开发们懒,而是上头要求的测试覆盖率高,但是又没有好用的工具,导致工作积压,最后只能舍弃掉这部分。

最近发现Spring+junit+mockito很好用,特别是对于DDD架构的项目,可以针对特定的代码层做单元测试,贼好用。

二,环境准备

1,首先是在spring环境下,引入mockito和junit
XML 复制代码
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>
2,使用mockito

1,使用 `@ExtendWith(MockitoExtension.class)` 注解让 junit 使用 Mockito 环境启动单元测试,这样 `@Mock` 和 `InjectMocks` 注解才会生效。

2,使用 `@Mock` 注解来 mock 一个对象,方便后续控制这个对象的行为。

3,使用 `@InjectMocks` 注解来标注一个对象(注意,对象的类型是具体的实现类,而不是接口),junit 会自动将标有 `@Mock` 注解的对象按需注入其中。

XML 复制代码
@ExtendWith(MockitoExtension.class)
class JunitPracticeTest {

    @Mock
    private JunitGateway junitGateway;
    @Mock
    private JunitMapper junitMapper;

    @InjectMocks
    private JunitServiceImpl junitService;

    @BeforeAll
    static void setup() {
        MockStaticUtil.mockStatic(BeanUtil.class);
    }

    @Test
    void testAdd() {
        when(BeanUtil.getBean(JunitGateway.class)).thenReturn(junitGateway);

		// ...
    }
}
3,覆盖率检测
XML 复制代码
<build>
      <plugins>
          <plugin>
              <groupId>org.jacoco</groupId>
              <artifactId>jacoco-maven-plugin</artifactId>
              <!-- 这里配置的include和exclude是对整个聚合报告生效的 -->
              <configuration>
                  <includes>
                      <!-- 仅统计app层和domain层的特定类 -->
                      <include>com/spice/junit/service/**/*</include>
                      <include>com/spice/junit/**/*DO.class</include>
                  </includes>
                  <excludes>
                      <!-- 排除这个特殊类,它是infrastructure层的一个类 -->
                      <exclude>com/spice/junit/service/RedisService.class</exclude>
                  </excludes>
              </configuration>
              <executions>
                  <execution>
                      <id>pre-test</id>
                      <goals>
                          <goal>prepare-agent</goal>
                      </goals>
                  </execution>
                  <execution>
                      <id>post-test</id>
                      <phase>test</phase>
                      <goals>
                          <!-- 在app模块中聚合jacoco的报告 -->
                          <goal>report-aggregate</goal>
                      </goals>
                      <configuration>
                          <!-- 配置在聚合报告中包含本模块(risk-app模块) -->
                          <includeCurrentProject>true</includeCurrentProject>
                      </configuration>
                  </execution>
              </executions>
          </plugin>
      </plugins>
  </build>

三,实战

1,新建测试类

idea中在类里ctrl+shift+T

注意:只有public方法才能生成单元测试方法,也只有public方法才需要单元测试。

2,添加注解和注入业务类里依赖的Bean

原业务类:

单元测试类:

将原业务类依赖的mapper注入到单元测试类。 将自己的实现类也注入到单元测试类。 下面的例子中还把BeanUtil这个静态的工具类先mock了,因为后面会用到,各种工具类都可以这样来mock。

3,根据原业务类方法里的逻辑写单元测试用例
4,redis等中间件都可以mock
5,捕获自定义异常
相关推荐
lpfasd1232 分钟前
模板方法模式(Template Method Pattern)
java·开发语言·设计模式·模板方法模式
hn小菜鸡29 分钟前
LeetCode 2529.正整数和负整数的最大计数
java·算法·leetcode
zh_199951 小时前
Spark面试精讲(上)
java·大数据·数据仓库·python·spark·数据库开发·数据库架构
小猫咪怎么会有坏心思呢1 小时前
华为OD机考-找座位-逻辑分析(JAVA 2025B卷)
java·开发语言·华为od
快乐肚皮1 小时前
Java的Arrays.sort():排序算法与优化分析
java·排序算法·归并排序·快速排序
西洼工作室1 小时前
Spring Boot常用依赖大全:从入门到精通
java·spring boot·后端
Hanson Huang1 小时前
【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(2)——Prompt(提示词)
java·人工智能·spring·spring ai
加油冲丫1 小时前
Java过滤器的基本概念
java·开发语言·后端·servlet
4060ti2 小时前
gradle 入门
java·gradle
.生产的驴2 小时前
SpringBoot 服务器监控 监控系统开销 获取服务器系统的信息用户信息 运行信息 保持稳定
服务器·spring boot·分布式·后端·spring·spring cloud·信息可视化