Springboot中使用Junit5(Jupiter)和Mockito

本文介绍了如何在Springboot 2.3.3.RELEASE项目中使用Junit5(Jupiter)和Mockito进行单元测试。文章详细讲解了环境配置,如依赖引入,以及用例配置,通过@ExtendWith(MockitoExtension.class)初始化Mockito。接着,展示了如何使用@InjectMocks和@Mock注解来注入和创建mock对象。文章还列举了一个测试类实例,并指出在使用Mockito时常见的错误——参数检验混淆,给出了错误代码和正确解决方案,并提供了Mockito官方文档和相关教程的参考链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果不关心Junit5和Mockito的,直接看使用方法

使用方法

环境配置

使用的是springboot版本为2.3.3.RELEASE,spring-boot-starter-test自带了 mockito-core,因此只需要在pom.xml中引入spring-boot-starter-test,即可使用junit5(即Junit Jupiter):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

用例配置

通过使用@ExtendWith(MockitoExtension.class)后,相当于在@BeforeEach调用MockitoAnnotations.initMocks(this),

Mockito使用

然后即可在测试类中使用注解@InjectMocks和@Mock注入对象,在方法中使用常用Mockito功能进行测试了

测试类:


import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class ServiceImplTest {
    @Mock
    private IOtherService otherService;

    @InjectMocks
    private ServiceImpl service;

    @Test
    public void xxxTest() {
        //使用when对depdService方法进行模拟,使用eq、anyString对参数进行检验,使用threnReturn返回结果
        when(otherService.doSomething(eq("参数"), anyString())).thenReturn("xxxx");
        assertEquals("xxxx", service.doSomething("参数"));
        verify(otherService).doSomething(eq("参数"), anyString());

        //直接使用原始值
        when(otherService.doSomething("参数1", "参数1aaa")).thenReturn("xxxx1");
        assertEquals("xxxx1", service.doSomething("参数1"));
        verify(otherService).doSomething("参数1", "参数1aaa");


        clearInvocations(otherService);//清除之前的调用
        assertNull(service.doSomething(""));
        //检测未被调用
        verifyNoInteractions(otherService);
    }

}

其他服务类:

import org.springframework.beans.factory.annotation.Autowired;

public class ServiceImpl {
    @Autowired
    private IOtherService otherService;

    public String doSomething(String param) {
        if (param.isEmpty()) {
            return null;
        }
        return otherService.doSomething(param, param + "aaa");
    }
}



public interface IOtherService {

    String doSomething(String param1, String param2);
}

常用Mockito功能参考

功能参考文档
模拟方法(行为打桩)2. How about some stubbing?
参数匹配3. Argument matchers?
调用次数验证4. Verifying exact number of invocations / at least x / never
模拟void方法的异常5. Stubbing void methods with exceptions
按顺序验证6. Verification in order
验证未被调用7. Making sure interaction(s) never happened on mock
验证多余的调用8. Finding redundant invocations
@Mock注解创建模拟对象 -9. Shorthand for mocks creation - @Mock annotation
链式模拟10. Stubbing consecutive calls (iterator-style stubbing)
doReturn()doThrow()
真实对象部分mock13. Spying on real objects
更改未存根调用的默认返回值14. Changing default return values of unstubbed invocations (Since 1.7)
捕获参数后再断言15. Capturing arguments for further assertions (Since 1.8.0)
真正的部分模拟(模拟对象调用真实对象)16. Real partial mocks (Since 1.8.0)
可序列化模拟20. Serializable mocks (Since 1.8.1)
新注解:@Captor, @Spy, @InjectMocks21. New annotations: @Captor, @Spy, @InjectMocks (Since 1.8.3)
超时验证22. Verification with timeout (Since 1.8.5)
@Spies和@InjectMocks注解23. Automatic instantiation of @Spies, @InjectMocks and constructor injection goodness (Since 1.9.0)
一行代码同时创建与模拟24. One-liner stubs (Since 1.9.0)
忽略验证25. Verification ignoring stubs (Since 1.9.0)
将调用委托给真实实例27. Delegate calls to real instance (Since 1.9.5)
监视或模拟抽象类30. Spying or mocking abstract classes (Since 1.10.12, further enhanced in 2.7.13 and 2.7.14)
Mockito 模拟可以跨类加载器序列化/反序列化31. Mockito mocks can be serialized / deserialized across classloaders (Since 1.10.0)
更好的泛型支持32. Better generic support with deep stubs (Since 1.10.0)
Mockito JUnit 规则33. Mockito JUnit rule (Since 1.10.17)
自定义验证失败消息35. Custom verification failure message (Since 2.1.0)
Java 8 Lambda 匹配器支持36. Java 8 Lambda Matcher Support (Since 2.1.0)
Java 8 自定义答案支持37. Java 8 Custom Answer Support (Since 2.1.0)
元数据和泛型类型保留38. Meta data and generic type retention (Since 2.1.0)
模拟final类、枚举和final方法39. Mocking final types, enums and final methods (Since 2.1.0)
新的 JUnit Jupiter (JUnit5+) 扩展45. New JUnit Jupiter (JUnit5+) extension
新的Mockito.lenient()和MockSettings.lenient()方法46. New Mockito.lenient() and MockSettings.lenient() methods (Since 2.20.0)
用于模拟静态方法的新 API48. New API for mocking static methods (Since 3.4.0)
用于模拟对象构造的新 API49. New API for mocking object construction (Since 3.5.0)
避免代码生成将模拟限制为接口时50. Avoiding code generation when restricting mocks to interfaces (Since 3.12.2)

Mockito使用错误记录

参数检验时原始参数与检验参数混用

错误代码:

when(otherService.doSomething("参数", anyString())).thenReturn("xxxx1");

错误提示:

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");

错误原因:方法参数未正确使用
正确代码:

when(otherService.doSomething(eq("参数"), anyString())).thenReturn("xxxx1");

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值