Mocktio 问题记录

一、Mockito使用when…thenReturn… 返回结果为null,不是预期值

  1. 实际入参与Mock方法中参数不一致。示例如下:
    实际方法: acDao.get(String id,String name);
    Mock方法: Mockito.when(acDao.get(Mockito.anyString(),Mockito.anyString())).thenReturn(new Ac());

    示例分析:
    实际方法中入参为String类型,Mockito.when(…)中设置参数也为String类型,两者一致,一般情况运行正常。但是当实际入参参数为null 时(acDao.get(null,“aaa”)),null并不等同于String,所以会导致Mock失效,返回为null。

    解决方法: a. 可以使用any()代替anyString(), any()代表任意类型参数;
    b. 可以使用精准匹配eq(…)

### Mockito `mock` 方法的使用说明 #### 什么是 `mock` 方法? 在单元测试中,`mock` 是一种用于创建虚拟对象的技术。通过这些虚拟对象可以模拟真实环境的行为而不依赖于实际的对象实例化。Mockito 的 `mock` 方法允许开发者轻松地创建这样的虚拟对象。 以下是关于 Mockito 中 `mock` 方法的一些核心概念和用法: --- #### 创建 Mock 对象 可以通过调用静态方法 `Mockito.mock(Class<T> classToMock)` 来创建一个指定类型的 mock 对象[^1]。 ```java // 创建 AbstractService 类型的一个 mock 实例 AbstractService abstractService = Mockito.mock(AbstractService.class); ``` 上述代码片段展示了如何为某个接口或类生成一个 mock 对象。 --- #### 模拟行为 (Stubbing) 对于非 `void` 方法,可以使用 `when(...).thenReturn(...)` 或者 `doReturn(...).when(...)` 来定义返回值[^2]。 ```java // 假设有一个名为 parentMethod 的方法 when(abstractService.parentMethod()).thenReturn("Mocked Value"); System.out.println(abstractService.parentMethod()); // 输出: Mocked Value ``` 当需要多次不同的返回值时,也可以链式设置多个返回值: ```java when(abstractService.parentMethod()) .thenReturn("First Call") .thenReturn("Second Call"); System.out.println(abstractService.parentMethod()); // 输出: First Call System.out.println(abstractService.parentMethod()); // 输出: Second Call ``` --- #### 模拟 Void 方法 由于 `void` 方法没有返回值,因此无法直接使用 `when(...).thenReturn(...)` 结构。此时应改用 `doNothing()`、`doThrow()` 或其他类似的结构来处理。 ```java // 如果 parentMethod 是一个 void 方法 doNothing().when(abstractService).parentVoidMethod(); abstractService.parentVoidMethod(); // 不会抛出异常 ``` 或者,在某些情况下可能希望触发特定异常: ```java doThrow(new RuntimeException("Error occurred")).when(abstractService).parentVoidMethod(); try { abstractService.parentVoidMethod(); } catch(RuntimeException e){ System.out.println(e.getMessage()); // 输出: Error occurred } ``` --- #### 验证交互次数 (Verification) 除了模拟行为外,还可以验证目标对象的方法是否被正确调用了适当次数。 ```java verify(abstractService, times(1)).parentMethod(); ``` 此段代码表示期望 `parentMethod` 被精确调用一次。如果不满足条件,则测试失败。 --- #### 组合 PowerMock 和 Spock 测试框架 针对更复杂的场景(比如抽象类),可借助第三方库如 **PowerMock** 提供额外支持。下面是一个简单的例子展示如何结合 Spock 和 PowerMock 完成此类需求: ```groovy @Grab('org.spockframework:spock-core:2.0-M4-groovy-3.0') @Grab('org.powermock:powermock-module-junit4:2.0.9') import org.mockito.Mockito import spock.lang.Specification import static org.powermock.api.mockito.PowerMockito.* class AbstractServiceTest extends Specification { def "test mocking abstract method with different values"() { given: AbstractService service = createPartialMock(AbstractService, 'parentMethod') when(service.parentMethod()).thenReturn("Value One").thenReturn("Value Two") expect: service.parentMethod() == "Value One" service.parentMethod() == "Value Two" } } ``` 注意这里引入了 Groovy DSL 特性以及 PowerMock 扩展功能以便更好地控制抽象成员函数的表现形式。 --- ### 总结 以上介绍了 Mockito 中 `mock` 方法的基础应用方式及其扩展技巧。无论是常规的 stubbing 还是对特殊类型(例如 void 返回值)的操作都提供了灵活的支持方案;同时配合外部工具能够进一步增强其能力范围以应对更加棘手的实际开发挑战。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值