Mockito怎么验证最后一次调用

本文介绍了使用Mockito框架进行单元测试时如何验证方法最后一次调用的参数,提供了三种方法并对比了各自的优缺点。

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

比如说你有一段代码像这样:

{
    ...
    A.add("1");
    ...
    A.add("what ever");
    ...
    A.add("2");
    A.delete("5");
    ...
}

你想验证A的add方法最后一次调用的时候参数是2,怎么做呢?

方法1 可以利用ArgumentCaptor去获得所有的实参,然后判断最后一个即可。

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
Mockito.verify(service, Mockito.atLeastOnce()).add(argument.capture());
List<String> values = argument.getAllValues();
assertTrue(values.contains("exception.message"));

如果没有atLeastOnce(),如果你的add方法被调用了多余一次的话,会报错:org.mockito.exceptions.verification.TooManyActualInvocations

方法2 如果你的service是一个很简单的POJO的话,也可以不mock它,直接用真实的,最后验证数据是不是你想要的就好了。但如果你的service还依赖于其他更多的对象,其它的对象又依赖于其它对象,这种方式有可能不是很容易的用真实数据,而且也导致你写的不是Unit Test,更像是Integration Test了。不过如果很容易生成,也可以试一试,毕竟测的更多也不是坏事。

方法3 直接用ArgumentCaptor的getValue(),这个会拿到最后一次的值,根据题意的需求,这个是目前最好的写法。但是方法一可以扩展到其它类型的测试,比如倒数第二个之类的。

更详细的讨论:

https://stackoverflow.com/questions/50503729/mockito-verify-the-last-call-on-a-mocked-object


原文:http://blog.youkuaiyun.com/hongchangfirst/article/details/80453203

作者:hongchangfirst

hongchangfirst的主页:http://blog.youkuaiyun.com/hongchangfirst


<think>嗯,用户想了解Mockito的使用方法和示例代码。首先,我需要回顾Mockito的基本概念,比如模拟对象、桩方法、验证交互等。记得用户可能需要从安装配置开始,所以应该先介绍如何添加Mockito依赖,比如Maven或Gradle的配置。然后,分步骤讲解创建模拟对象的不同方法,比如使用@Mock注解或者Mockito.mock()方法。 接下来是桩方法设置,这部分很重要,用户通常需要知道如何让模拟对象返回特定的值或者抛出异常。要举一些具体的例子,比如when(...).thenReturn(...)的结构,可能还要提到thenThrow和thenAnswer的用法。 然后是验证交互的部分,用户可能想知道如何检查方法是否被调用调用次数是否正确。需要解释verify的基本用法,以及使用数匹配器如any()、eq()的注意事项。 还有,用户提到考了引用中的代码,特别是使用@Mock和@InjectMocks的示例,所以需要详细说明这些注解的使用步骤,包括初始化注解的方式,比如MockitoAnnotations.openMocks(this)或者JUnit的MockitoExtension。 另外,可能需要提到Mockito的一些高级功能,比如数捕获、部分模拟,或者与Spring框架的集成,但根据用户的问题,可能基础内容更重要。需要确保示例代码正确,语法无误,特别是Java和可能的Kotlin代码,不过用户提供的引用中有Kotlin项目地址,但问题主要是Java的示例,所以重点放在Java上。 最后,生成的相关问题要覆盖用户可能进一步想知道的内容,比如与JUnit5的整合、异常测试、Spring集成、数捕获等。确保每个步骤都有清晰的说明,代码示例正确,并且引用正确对应的考来源。</think>### Mockito 使用指南 Mockito 是一个流行的 Java 测试框架,用于模拟依赖对象的行为,简化单元测试。以下是核心使用方法和示例: --- #### 1. **添加依赖** 在项目中引 Mockito(以 Maven 为例): ```xml <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> ``` 若使用 Kotlin,可考 `mockito-kotlin` 扩展库[^1]。 --- #### 2. **创建模拟对象** **方式一:通过注解** ```java public class CustomerServiceTest { @Mock private CustomerDao daoMock; // 模拟对象 @InjectMocks private CustomerService service; // 自动注依赖 @Before public void setUp() { MockitoAnnotations.openMocks(this); // 初始化注解 } } ``` **方式二:通过静态方法** ```java CustomerDao daoMock = Mockito.mock(CustomerDao.class); ``` --- #### 3. **桩方法(Stubbing)** 定义模拟对象的行为: ```java // 当调用 daoMock.findById(1L) 时返回预设对象 Mockito.when(daoMock.findById(1L)) .thenReturn(new Customer("Alice")); // 抛出异常 Mockito.when(daoMock.delete(any())) .thenThrow(new RuntimeException()); // 动态返回 Mockito.when(daoMock.getName()) .thenAnswer(invocation -> "Response"); ``` --- #### 4. **验证交互** 检查方法是否按预期调用: ```java // 验证 daoMock.save() 被调用一次 Mockito.verify(daoMock, times(1)).save(any(Customer.class)); // 验证调用 Mockito.verify(daoMock, never()).deleteAll(); ``` --- #### 5. **数匹配器** 灵活匹配输数: ```java Mockito.when(daoMock.findByAge(Mockito.anyInt())) // 任意整数 .thenReturn(new Customer()); Mockito.verify(daoMock).update(Mockito.eq("id123"), any()); // 精确匹配第一个数 ``` --- #### 6. **高级用法示例** **捕获数值:** ```java ArgumentCaptor<Customer> captor = ArgumentCaptor.forClass(Customer.class); Mockito.verify(daoMock).save(captor.capture()); Customer capturedCustomer = captor.getValue(); ``` **部分模拟(Spy):** ```java List<String> realList = new ArrayList<>(); List<String> spyList = Mockito.spy(realList); // 覆盖部分方法 Mockito.when(spyList.size()).thenReturn(100); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值