gpt4 book ai didi

java - 使用 Mockito 的 ArgumentCaptor 类匹配子类

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:42:33 28 4
gpt4 key购买 nike

下面的代码显示了我的问题。实际上,我正在尝试使用 Mockito 的 ArgumentCaptor 来验证是否使用某个具体类调用了一次方法。如果可能的话,我想在这里使用 ArgumentCaptor,但我开始怀疑我需要改用自定义 ArgumentMatcher。

问题是 Mockito.verify(mocked).receive(captor.capture()); 行(编辑:将此添加到下面的代码中)失败并出现 TooManyActualInvocations 异常(改为 2 1).我想了解为什么会发生这种情况 - 是 Mockito 的实现不当还是由泛型类型删除引起的限制?

public class FooReceiver {
public void receive(Foo foo) {

}
}

public interface Foo {
}

public class A implements Foo {
}

public class B implements Foo {
}

public class TestedClass {
private FooReceiver receiver;
public TestedClass(FooReceiver receiver) {
this.receiver = receiver;
}

public void doStuff() {
receiver.receive(new A());
receiver.receive(new B());
}
}

public class MyTest {

@Test
public void testingStuff() {
// Setup
FooReceiver mocked = Mockito.mock(FooReceiver.class);
TestedClass t = new TestedClass(mocked);

// Method under test
t.doStuff();

// Verify
ArgumentCaptor<B> captor = ArgumentCaptor.forClass(B.class);
Mockito.verify(mocked).receive(captor.capture()); // Fails here

Assert.assertTrue("What happened?", captor.getValue() instanceof B);
}
}

编辑:对于任何感兴趣的人,我最终这样做了:

// Verify
final B[] b = new B[1];
ArgumentMatcher<B> filter = new ArgumentMatcher<B>() {
@Override
public boolean matches(Object argument) {
if(argument instanceof B) {
b[0] = (B) argument;
return true;
}
return false;
}
}
Mockito.verify(mocked).receive(Mockito.argThat(filter));

最佳答案

据我所知,这是一个限制/实现不力。在查看 org.mockito.internal.matchers.CapturingMatcher 时有

public boolean matches(Object argument) {
return true;
}

意味着它匹配每个参数/类。

这导致 org.mockito.internal.matchers.CapturingMatcher#getAllValues返回 List<B>但实际上包含一个 A和一个B导致 ClassCastException在运行时尝试将它们获取为 B .

List<Object> arguments; // the invocations

// adds a new invocation
public void captureFrom(Object argument) {
// ...
this.arguments.add(argument);
// ...
}

// return the list of arguments, using raw types remove any compiler checks for validity,
// the returned List contains elements that are not of type T
public List<T> getAllValues() {
// ...
return new ArrayList<T>((List) arguments);
// ...
}

这应该可以通过更改 org.mockito.ArgumentCaptor 来解决。以一种它通过其 Class<? extends T> clazz 的方式进入CapturingMatcher因此正确传递类型信息,启用正确的 matches实现并消除对强制转换/原始类型使用的需要。

关于java - 使用 Mockito 的 ArgumentCaptor 类匹配子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5403706/

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