mockito_Mockito ArgumentCaptor,@Captor注释

文章来源:https://blog.csdn.net/cunchi4221/article/details/107476971
https://www.journaldev.com/21892/mockito-argumentcaptor-captor-annotation
https://www.jianshu.com/p/adee7d28cb59

mockito

Mockito ArgumentCaptor is used to capture arguments for mocked methods. ArgumentCaptor is used with Mockito verify() methods to get the arguments passed when any method is called. This way, we can provide additional JUnit assertions for our tests.

Mockito ArgumentCaptor用于捕获模拟方法的参数。 ArgumentCaptor与Mockito verify()方法一起使用,以获取调用任何方法时传递的参数。 这样,我们可以为测试提供其他JUnit断言 。

Mockito ArgumentCaptor (Mockito ArgumentCaptor)
We can create ArgumentCaptor instance for any class, then its capture() method is used with verify() methods.

我们可以为任何类创建ArgumentCaptor实例,然后将其capture()方法与verify()方法一起使用。

Finally, we can get the captured arguments from getValue() and getAllValues() methods.

最后,我们可以从getValue()和getAllValues()方法获取捕获的参数。

getValue() method can be used when we have captured a single argument. If the verified method was called multiple times then getValue() method will return the latest captured value.

当我们捕获单个参数时,可以使用getValue()方法。 如果多次调用经过验证的方法,则getValue()方法将返回最新捕获的值。

If multiple arguments are captured, call getAllValues() to get the list of arguments.

如果捕获了多个参数,请调用getAllValues()以获取参数列表。

Mockito ArgumentCaptor示例 (Mockito ArgumentCaptor Example)
Let’s say we have a class defined as:

假设我们有一个定义为的类:


class MathUtils {
	public int add(int x, int y) {
		return x + y;
	}

	public boolean isInteger(String s) {
		try {
			Integer.parseInt(s);
		} catch (NumberFormatException e) {
			return false;
		}
		return true;
	}
	
	public long squareLong(long l) {
		return l*l;
	}
}

We can write our test case and use ArgumentCaptor as shown below.

我们可以编写测试用例并使用ArgumentCaptor,如下所示。


@Test
void test() {
	MathUtils mockMathUtils = mock(MathUtils.class);
	when(mockMathUtils.add(1, 1)).thenReturn(2);
	when(mockMathUtils.isInteger(anyString())).thenReturn(true);

	ArgumentCaptor acInteger = ArgumentCaptor.forClass(Integer.class);
	ArgumentCaptor acString = ArgumentCaptor.forClass(String.class);

	assertEquals(2, mockMathUtils.add(1, 1));
	assertTrue(mockMathUtils.isInteger("1"));
	assertTrue(mockMathUtils.isInteger("999"));

	verify(mockMathUtils).add(acInteger.capture(), acInteger.capture());
	List allValues = acInteger.getAllValues();
	assertEquals(List.of(1, 1), allValues);
	
	verify(mockMathUtils, times(2)).isInteger(acString.capture());
	List allStringValues = acString.getAllValues();
	assertEquals(List.of("1", "999"), allStringValues);
}

Mockito @Captor (Mockito @Captor)
We can use @Captor annotation to create argument captor at field level. So instead of initializing field level ArgumentCaptor as:

我们可以使用@Captor批注在字段级别创建参数捕获器。 因此,与其将字段级别的ArgumentCaptor初始化为:


ArgumentCaptor acLong = ArgumentCaptor.forClass(Long.class);

We can use @Captor as:

我们可以将@Captor用作:


@Captor ArgumentCaptor acLong;

Note that we have to call MockitoAnnotations.initMocks(this); before test methods to get it initialized by Mockito framework.

注意,我们必须调用MockitoAnnotations.initMocks(this); 在通过Mockito框架对其进行初始化的测试方法之前。

Mockito @Captor示例 (Mockito @Captor Example)
Here is a simple example of @Captor annotation.

这是@Captor批注的简单示例。


class MockitoArgumentCaptorExamples {

	@Captor ArgumentCaptor acLong;

	@Test
	void test() {
		MathUtils mockMathUtils = mock(MathUtils.class);
		when(mockMathUtils.squareLong(2L)).thenReturn(4L);
		assertEquals(4L, mockMathUtils.squareLong(2L));
		verify(mockMathUtils).squareLong(acLong.capture());
		assertTrue(2 == acLong.getValue());
	}
}



利用ArgumentCaptor捕获方法参数进行验证

在某些场景中,不光要对方法的返回值和调用进行验证,同时需要验证一系列交互后所传入方法的参数。那么我们可以用参数捕获器来捕获传入方法的参数进行验证,看它是否符合我们的要求。

ArgumentCaptor介绍

通过ArgumentCaptor对象的forClass(Class clazz)方法来构建ArgumentCaptor对象。然后便可在验证时对方法的参数进行捕获,最后验证捕获的参数值。如果方法有多个参数都要捕获验证,那就需要创建多个ArgumentCaptor对象处理。

ArgumentCaptor的API

argument.capture() 捕获方法参数
argument.getValue() 获取方法参数值,如果方法进行了多次调用,它将返回最后一个参数值
argument.getAllValues() 方法进行多次调用后,返回多个参数值

应用实例

@Test  
public void argumentCaptorTest() {  
    List mock = mock(List.class);  
    List mock2 = mock(List.class);  
    mock.add("John");  
    mock2.add("Brian");  
    mock2.add("Jim");  
      
    ArgumentCaptor argument = ArgumentCaptor.forClass(String.class);  
      
    verify(mock).add(argument.capture());  
    assertEquals("John", argument.getValue());  
      
    verify(mock2, times(2)).add(argument.capture());  
  
    assertEquals("Jim", argument.getValue());  
    assertArrayEquals(new Object[]{"Brian","Jim"},argument.getAllValues().toArray());  
}  

首先构建ArgumentCaptor需要传入捕获参数的对象,例子中是String。接着要在verify方法的参数中调用argument.capture()方法来捕获输入的参数,之后argument变量中就保存了参数值,可以用argument.getValue()获取。当某个对象进行了多次调用后,如mock2对象,这时调用argument.getValue()获取到的是最后一次调用的参数。如果要获取所有的参数值可以调用argument.getAllValues(),它将返回参数值的List。

猜你喜欢

转载自blog.csdn.net/yangyangrenren/article/details/119459172