gpt4 book ai didi

java - Mockito 监视具有内部方法引用的类

转载 作者:行者123 更新时间:2023-12-02 09:36:01 24 4
gpt4 key购买 nike

当使用 @Spy 注释监视服务并让 Mockito 创建服务器与显式调用构造函数时,我发现行为有所不同。

public class MyService {
private final Supplier<String> methodBCall;

public MyService() {
methodBCall = this::methodB;
}

public void methodA() {
methodBCall.get();
}

public String methodB() {
return "methodB";
}
}
@RunWith(MockitoJUnitRunner.class)
public class MyTest {

@Spy
private MyService myService1;
@Spy
private MyService myService2 = new MyService();

@Test
public void testSucceeds() {
myService1.methodA();
verify(myService1, times(1)).methodA();
verify(myService1, times(1)).methodB();
}

@Test
public void testFails() {
myService2.methodA();
verify(myService2, times(1)).methodA();
verify(myService2, times(1)).methodB();
}
}

失败的测试失败

Wanted but not invoked:
myService2.methodB();
-> at com.phemi.services.policy.impl.MyTest.testFails

为什么这两者的行为不同? Mockito 正在做什么来初始化 myService1 以使其能够监视 methodB?

这是一个简化的示例,在我的例子中,为了正确测试我的服务,我需要使用参数调用其构造函数(因此不能将 @Spy 与默认构造函数一起使用)。但是,当我这样做时,我无法正确验证方法调用。

最佳答案

myService2 上的 spy 仅在构造对象后创建,因此在 构造函数 中调用方法没有帮助,因为它包含对初始对象(不是 spy 对象)的方法引用。

当您比较两种情况的实现时,差异会变得更加明显:

Mockito.spy(Class)

public static <T> T spy(Class<T> classToSpy) {
return MOCKITO_CORE.mock(classToSpy, withSettings()
.useConstructor()
.defaultAnswer(CALLS_REAL_METHODS));
}

Mockito.spy(Object)

public static <T> T spy(T object) {
return MOCKITO_CORE.mock((Class<T>) object.getClass(), withSettings()
.spiedInstance(object)
.defaultAnswer(CALLS_REAL_METHODS));
}

正如您所看到的第一种情况,基于一个类(如果没有创建 @Spy 实例,则使用该类),首先创建一个模拟并在模拟对象上使用构造函数。

在第二种情况下,不考虑构造函数,而是创建不同的实例。

关于java - Mockito 监视具有内部方法引用的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57516634/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com