JUnit 5和Mockito单元测试

当谈及使用JUnit 5和Mockito进行单元测试时,了解如何结合两者来测试Java代码是至关重要的。在本文中,我们将深入探讨如何编写详细的单元测试,确保代码的可靠性和稳定性。

步骤一:设置项目依赖

首先,确保你的项目中包含了JUnit 5和Mockito的依赖。这两者可以通过Maven或Gradle进行添加。以下是Maven中添加依赖的示例:

xml 复制代码
<dependencies>
    <!-- JUnit 5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.x.x</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.x.x</version>
        <scope>test</scope>
    </dependency>
    
    <!-- Mockito -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>x.x.x</version>
        <scope>test</scope>
    </dependency>
</dependencies>

步骤二:创建被测试的类

我们将从一个简单的示例开始。假设我们有一个名为 Calculator 的类,其中包含基本的数学运算方法。

java 复制代码
public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }
}

步骤三:编写单元测试

现在,让我们针对 Calculator 类编写单元测试。

java 复制代码
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class CalculatorTest {

    @Test
    public void testAdd() {
        Calculator calculator = new Calculator();
        int result = calculator.add(10, 20);
        assertEquals(30, result, "10 + 20 should equal 30");
    }

    @Test
    public void testSubtract() {
        Calculator calculator = new Calculator();
        int result = calculator.subtract(20, 10);
        assertEquals(10, result, "20 - 10 should equal 10");
    }
}

这里,我们使用了JUnit 5的 @Test 注解来标记测试方法,并使用了 assertEquals() 方法来验证预期结果和实际结果是否相等。

步骤四:使用Mockito进行模拟

现在,假设 Calculator 类依赖于另一个类 MathUtil 来执行数学运算。

java 复制代码
public class MathUtil {
    public int multiply(int a, int b) {
        return a * b;
    }
}

我们可以使用Mockito来模拟 MathUtil 类,并对 Calculator 类进行更深入的测试。

java 复制代码
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class CalculatorTest {

    @Test
    public void testMultiply() {
        MathUtil mathUtil = mock(MathUtil.class);
        when(mathUtil.multiply(2, 3)).thenReturn(6);

        Calculator calculator = new Calculator(mathUtil);
        int result = calculator.multiply(2, 3);
        
        assertEquals(6, result, "2 * 3 should equal 6");
    }
}

在这个示例中,我们使用了Mockito的 mock() 方法创建了一个 MathUtil 类的模拟对象,并使用 when().thenReturn() 方法设定了当调用 multiply() 方法时,返回预期的值。

将结合上面提供的几种情况,展示如何在一个单元测试类中使用JUnit 5和Mockito来编写不同类型的测试。

java 复制代码
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class CalculatorTest {

    @Test
    public void testAdd() {
        Calculator calculator = new Calculator();
        int result = calculator.add(10, 20);
        assertEquals(30, result, "10 + 20 should equal 30");
    }

    @Test
    public void testSubtract() {
        Calculator calculator = new Calculator();
        int result = calculator.subtract(20, 10);
        assertEquals(10, result, "20 - 10 should equal 10");
    }

    @ParameterizedTest
    @CsvSource({"2, 3, 6", "5, 5, 25", "4, 0, 0"})
    public void testMultiply(int a, int b, int expectedResult) {
        Calculator calculator = new Calculator();
        int result = calculator.multiply(a, b);
        assertEquals(expectedResult, result, () -> a + " * " + b + " should equal " + expectedResult);
    }

    @Test
    public void testComplexOperation() {
        MathUtil mathUtil = mock(MathUtil.class);
        Calculator calculator = new Calculator(mathUtil);

        calculator.complexOperation(3, 4);

        verify(mathUtil, times(1)).multiply(3, 4);
        verify(mathUtil, times(1)).multiply(anyInt(), eq(2));
    }

    @Test
    public void testDivideByZero() {
        Calculator calculator = new Calculator();

        Exception exception = assertThrows(IllegalArgumentException.class, () -> {
            calculator.divide(10, 0);
        });

        assertEquals("Divisor cannot be zero", exception.getMessage());
    }
}

这个例子展示了一个包含多种测试情况的单元测试类。其中包括了普通的方法测试、参数化测试、模拟对象的方法验证以及异常测试

总结

通过JUnit 5和Mockito,我们能够轻松地编写详细的单元测试。这种实践有助于确保代码在各种情况下都能按预期工作。JUnit 5提供了丰富的断言功能,而Mockito则帮助我们模拟和隔离依赖,从而更全面地测试代码。结合使用这两个工具,能够提高代码质量并降低潜在的错误风险。

相关推荐
前端若水19 小时前
智能体开发与传统软件开发的核心区别
网络·人工智能·python·开源·log4j
QH139292318801 天前
思仪 Ceyear 5256C 5G 终端综合测试仪
单片机·单元测试·集成测试·嵌入式实时数据库
汽车仪器仪表相关领域2 天前
Debron OVM 1052 光学关门速度仪:汽车门盖检测的高精度便携工具 + 生产线适配 + 耐久性监测,整车制造与质量控制的黄金标准
人工智能·功能测试·单元测试·汽车·制造·可用性测试
Sandy_Star3 天前
1.9 民法典及社会保险法制度规定
单元测试
xiufeia3 天前
后端项目初始化的一些小坑点
java·junit·maven·idea
Sandy_Star3 天前
1.7 税务行政法律救济
大数据·单元测试
zlpzlpzyd3 天前
slf4j中jcl-over-slf4j、jul-to-slf4j、log4j-over-slf4j、slf4j-api的区别是什么
java·开发语言·log4j
Kiyra4 天前
Query Rewrite 不是越智能越好:RAG 检索的精确词保护与动态召回
redis·websocket·junit·单元测试·json
计算机安禾4 天前
【c++面向对象编程】第9篇:友元(friend):破坏封装的“特权”——真的有害吗?
java·c++·log4j
华万通信king4 天前
腾讯会议API集成测试实战:从单元测试到端到端自动化
单元测试·自动化·腾讯会议