1.什么是Mockito?
Mockito 是一个强大的 Java 测试框架,专门用于创建和管理模拟对象。它允许我们:
- 创建模拟对象:通过简单的语法创建对象的模拟版本。
- 定义行为:设置模拟对象的方法返回值或抛出异常。
- 验证交互:验证某些方法是否被调用,或调用了几次。
1.1Mockito的核心功能
- 模拟(Mocking):创建一个类或接口的模拟对象。
- 桩方法(Stubbing):定义模拟对象的方法行为,例如返回特定值或抛出异常。
- 验证(Verification):检查模拟对象的方法是否按照预期被调用。
2.引入Mockito
要在项目中使用 Mockito,我们首先需要在 pom.xml 中添加其依赖:
java
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
3.一个简单的Mockito测试
例:银行转账服务
我们有一个银行转账服务 TransferService,它依赖于一个账户服务 AccountService 来完成实际的资金转移。在测试转账功能时,我们不希望真的去修改账户中的金额,因此可以使用 Mockito 来模拟 AccountService。
被测试类 TransferService.java:
java
public class TransferService {
private AccountService accountService;
public TransferService(AccountService accountService) {
this.accountService = accountService;
}
public boolean transfer(String fromAccount, String toAccount, double amount) {
if (accountService.withdraw(fromAccount, amount)) {
return accountService.deposit(toAccount, amount);
}
return false;
}
}
依赖类 AccountService.java:
java
public interface AccountService {
boolean withdraw(String account, double amount);
boolean deposit(String account, double amount);
}
测试类 TransferServiceTest.java:
java
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class TransferServiceTest {
private AccountService accountService;
private TransferService transferService;
@Before
public void setUp() {
accountService = Mockito.mock(AccountService.class); // 创建AccountService的模拟对象
transferService = new TransferService(accountService); // 传入模拟对象
}
@Test
public void testTransferSuccess() {
when(accountService.withdraw("123", 100.0)).thenReturn(true); // 设置 withdraw 方法的返回值
when(accountService.deposit("456", 100.0)).thenReturn(true); // 设置 deposit 方法的返回值
boolean result = transferService.transfer("123", "456", 100.0);
assertTrue(result); // 断言转账成功
verify(accountService).withdraw("123", 100.0); // 验证 withdraw 方法被调用
verify(accountService).deposit("456", 100.0); // 验证 deposit 方法被调用
}
@Test
public void testTransferFailure() {
when(accountService.withdraw("123", 100.0)).thenReturn(false); // 模拟 withdraw 失败
boolean result = transferService.transfer("123", "456", 100.0);
assertFalse(result); // 断言转账失败
verify(accountService).withdraw("123", 100.0); // 验证 withdraw 被调用
verify(accountService, never()).deposit(anyString(), anyDouble()); // 验证 deposit 没有被调用
}
}
解释:
- 创建模拟对象 :使用 Mockito.mock(AccountService.class) 创建 AccountService
的模拟对象。 - 设置桩方法 :通过 when(...).thenReturn(...) 方法,定义模拟对象的方法返回特定值。例如:当
withdraw 方法被调用时,返回 true。 - 验证交互 :使用 verify(...) 来验证特定方法是否被调用,以及调用次数。在
testTransferSuccess 中,我们验证了 withdraw 和 deposit 方法都被正确调用。
4.Mockito常用功能
4.1模拟异常
在测试错误处理逻辑时,模拟方法抛出异常也很有用。Mockito 提供了 thenThrow() 来模拟异常行为。
java
@Test(expected = RuntimeException.class)
public void testWithdrawThrowsException() {
when(accountService.withdraw("123", 100.0)).thenThrow(new RuntimeException("Insufficient funds"));
transferService.transfer("123", "456", 100.0);
}
4.2参数匹配
Mockito 提供了多种参数匹配器,用于更加灵活地模拟方法。例如:
- anyString():匹配任意字符串。
- anyDouble():匹配任意 double 类型参数。
- eq(value):匹配指定的值。
java
when(accountService.deposit(anyString(), eq(100.0))).thenReturn(true);
4.3验证调用次数
可以验证方法是否被调用了指定次数:
java
verify(accountService, times(1)).withdraw("123", 100.0); // 验证 withdraw 方法被调用一次
4.4重置模拟对象
有时需要重置模拟对象的状态,Mockito 提供了 reset() 方法:
java
verify(accountService, times(1)).withdraw("123", 100.0); // 验证 withdraw 方法被调用一次
4.5重置模拟对象
有时我们需要重置模拟对象的状态,Mockito 提供了 reset() 方法:
java
reset(accountService);
有兴趣的小伙伴可以关注我的公众号【知识星球站】一起讨论学习!!