java 我可以混合 Argument Captor 和常规匹配器吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32716763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I mix Argument Captor and a regular matcher?
提问by kavai77
I need to verify a method with multiple parameter in Mockito, but need to capture only one argument, the others I need only a simple matcher. Is that possible?
我需要在 Mockito 中验证具有多个参数的方法,但只需要捕获一个参数,其他参数我只需要一个简单的匹配器。那可能吗?
For instance, if I have:
例如,如果我有:
@Mock
private Map<K,V> mockedMap;
...
ArgumentCaptor<K> argument = ArgumentCaptor.forClass(K.class);
verify(mockedMap).put(argument.capture(), any(V.class));
In this case do I need to write a captor for each argument in spite of the fact I need to capture only the first argument?
在这种情况下,尽管我只需要捕获第一个参数,但我是否需要为每个参数编写一个捕获器?
回答by Jeff Bowman
In this case do I need to write a captor for each argument in spite of the fact I need to capture only the first argument?
在这种情况下,尽管我只需要捕获第一个参数,但我是否需要为每个参数编写一个捕获器?
durron597's answeris correct—you do not need to captureall arguments if you want to capture one of them. One point of clarification, though: a call to ArgumentCaptor.capture()
counts as a Mockito matcher, and in Mockito if you use a matcherfor any method argument you do have to use a matcher for all arguments.
durron597 的答案是正确的——如果您想捕获其中一个参数,则无需捕获所有参数。澄清一点,虽然:将呼叫ArgumentCaptor.capture()
计为一个匹配的Mockito,并在如果的Mockito您使用匹配任何方法的参数,你就必须使用匹配的所有参数。
For a method yourMock.yourMethod(int, int, int)
and an ArgumentCaptor<Integer> intCaptor
:
对于一个方法yourMock.yourMethod(int, int, int)
和一个ArgumentCaptor<Integer> intCaptor
:
/* good: */ verify(yourMock).yourMethod(2, 3, 4); // eq by default
/* same: */ verify(yourMock).yourMethod(eq(2), eq(3), eq(4));
/* BAD: */ verify(yourMock).yourMethod(intCaptor.capture(), 3, 4);
/* fixed: */ verify(yourMock).yourMethod(intCaptor.capture(), eq(3), eq(4));
These also work:
这些也有效:
verify(yourMock).yourMethod(intCaptor.capture(), eq(5), otherIntCaptor.capture());
verify(yourMock).yourMethod(intCaptor.capture(), anyInt(), gt(9000));
回答by durron597
Of course it works. Why wouldn't it?
当然有效。为什么不呢?
import java.util.Map;
import org.junit.*;
import org.mockito.*;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
public class MockitoTest {
@Mock
private Map<Integer, String> mockedMap;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testCaptor() {
mockedMap.put(5, "Hello World!");
ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
verify(mockedMap).put(argument.capture(), any(String.class));
assertEquals(5L, argument.getValue().longValue());
}
}
This works correctly and passes.
这工作正常并通过。
As an aside, you almost never want to mock data structures such as List
and Map
, because it's a giant pain to correctly mock all their behavior and most code won't be very happy if you, for example, add an element and then the element doesn't actually exist. In your case, it would probably be better to create a partial mock (using Mockito.spy
) than an actual mock.
顺便说一句,您几乎从不想模拟List
和这样的数据结构Map
,因为正确模拟它们的所有行为是一个巨大的痛苦,并且如果您例如添加一个元素然后该元素没有,大多数代码将不会很高兴'实际上不存在。在您的情况下,创建部分模拟(使用Mockito.spy
)可能比实际模拟更好。
回答by dgoel
At least with Mockito 1.10.19 you need to pass a captor for all arguments.
至少在 Mockito 1.10.19 中,您需要为所有参数传递一个捕获器。
So adding to Jeff Bowman's answer, if you need to capture even a single argument you would need to do:
因此,添加 Jeff Bowman 的答案,如果您需要捕获甚至单个参数,则需要执行以下操作:
verify(yourMock).yourMethod(intCaptor.capture(), otherIntCaptor.capture(), otherIntCaptor.capture());