mockito验证参数_Mockito验证

mockito验证参数

本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。

在本课程中,您将深入了解Mockito的魔力。 您将了解有关“模拟”,“间谍”和“部分模拟”的信息,以及它们相应的存根行为。 您还将看到使用测试双打和对象匹配器进行验证的过程。 最后,讨论了使用Mockito的测试驱动开发(TDD),以了解该库如何适合TDD的概念。 在这里查看

1.什么是验证?

验证是确认模拟行为的过程。 这对于确定我们正在测试的类是否已按预期方式与其任何依赖项进行交互非常有用。 有时我们对从Mock返回的值不感兴趣,但是对被测类如何与之交互,发送什么值或调用它的频率感兴趣。 确认此行为的过程是验证,Mockito提供了许多工具来允许我们执行此操作。

2.使用verify()

Mockito工具箱中用于执行验证的主要工具是org.mockito.Mockito.verify()方法。 verify方法将Mock对象作为参数,并返回与Mock相同的Class的实例,从而允许您调用Class的方法,Mockito将该Class的方法解释为验证与该方法是否存在某种交互的请求。

让我们再次看一下上一教程中的打印机界面。

public interface Printer {
	
	void printTestPage();

}

我们可以创建一个简单的单元测试来演示使用模拟打印机进行验证

import static org.mockito.Mockito.verify;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class PrinterTest {

	@Mock
	private Printer printer;

	@Test
	public void simple_interaction_verification() {
		// Given
		
		// When
		printer.printTestPage();
		
		// Then
		verify(printer).printTestPage();		
	}
}

我们可以看到我们的单元测试首先调用printer.printTestPage() 。 这是在模拟被测类中的可能交互,但是为了简单起见,我们在单元测试类中进行了模拟。 下一个调用是对verify(printer).printTestPage()的调用。 这指示Mockito检查是否对Mock打印机的printTestPage()方法进行了一次调用。

请仔细注意调用的语法, verify()的参数是Mock对象,而不是方法调用。 如果我们放置了verify(printer.printTestPage())我们将产生一个编译错误。 将此与存根中给定的/ when语法相对应,语法形式为when(mockObject.someMethod()).thenReturn(...)

如果我们没有在此调用上方调用printTestPage()来验证Mockito会生成验证错误,通知我们没有调用printTestPage() ,则该代码如下所示:

Wanted but not invoked:
printer.printTestPage();
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification(PrinterTest.java:24)
Actually, there were zero interactions with this mock.

另外,如果我们再次调用printTestPage() Mockito会产生一个验证错误,通知我们printTestPage()调用过多。 该错误如下所示:

org.mockito.exceptions.verification.TooManyActualInvocations: 
printer.printTestPage();
Wanted 1 time:
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification(PrinterTest.java:25)
But was 2 times. Undesired invocation:
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification(PrinterTest.java:22)

有用的是,错误告诉我们哪一行代码包含了多余的调用-在本例中为PrinterTest.java第22行。

但是,如果我们想与我们的Mock进行多次交互,该怎么办? Mockito支持吗? 毫无疑问,答案是肯定的!

verify()方法采用org.mockito.verification.VerificationMode类型的第二个参数,该参数可用于提供有关与模拟的所需交互的其他详细信息。

使用内置的验证模式

像往常一样,Mockito在org.mockito.Mockito中提供了许多方便的静态方法来创建VerificationModes,例如:

times(int)
这将验证该方法被调用次数。

@Test
public void simple_interaction_verification_times_1() {
	// Given
		
	// When
	printer.printTestPage();
		
	// Then
	verify(printer, times(1)).printTestPage();		
}

请注意, verify(mock)verify(mock, times(1))的别名。

当然,我们可以使用times()验证多个交互

@Test
public void simple_interaction_verification_times_3() {
	// Given
		
	// When
	printer.printTestPage();
	printer.printTestPage();
	printer.printTestPage();
		
	// Then
	verify(printer, times(3)).printTestPage();		
}

当实际的调用次数与预期的次数不匹配时,此VerificationMode将产生有用的错误。

调用不足:

org.mockito.exceptions.verification.TooLittleActualInvocations: 
printer.printTestPage();
Wanted 3 times:
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:49)
But was 2 times:
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:45)

调用过多:

org.mockito.exceptions.verification.TooManyActualInvocations: 
printer.printTestPage();
Wanted 3 times:
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:50)
But was 4 times. Undesired invocation:
-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:47)

atLeastOnce()atLeast(int)
这将验证该方法至少被调用了给定的次数。

@Test
public void simple_interaction_verification_atleastonce() {
	// Given
		
	// When
	printer.printTestPage();
	printer.printTestPage();
		
	// Then
	verify(printer, atLeastOnce()).printTestPage();		
}
@Test
public void simple_interaction_verification_atleast_2() {
	// Given
		
	// When
	printer.printTestPage();
	printer.printTestPage();
	printer.printTestPage();
		
	// Then
	verify(printer, atLeast(2)).printTestPage();		
}

和往常一样,我们得到全面的错误报告:

org.mockito.exceptions.verification.TooLittleActualInvocations: 
printer.printTestPage();
Wanted *at least* 2 times:
-> at com.javacodegeeks.hu
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用 Mockito 的链式调用来模拟多层调用的方法。例如,假设您有一个名为 `userService` 的服务,该服务中有一个名为 `getUserAddress` 的方法,该方法将调用另一个名为 `addressService` 的服务中的方法。您可以使用以下代码模拟这两个方法的调用: ``` // 创建 Mock 对象 UserService userService = Mockito.mock(UserService.class); AddressService addressService = Mockito.mock(AddressService.class); // 模拟 getUserAddress 方法 Mockito.when(userService.getUserAddress(Mockito.anyLong())).thenAnswer(invocation -> { Long userId = invocation.getArgument(0); Address address = addressService.getAddress(userId); return address; }); // 模拟 getAddress 方法 Mockito.when(addressService.getAddress(Mockito.anyLong())).thenReturn(new Address("123 Main St.")); ``` 在上面的代码中,我们首先创建了 `UserService` 和 `AddressService` 的 Mock 对象。然后,我们使用 `when` 方法来模拟 `getUserAddress` 方法的调用。在模拟 `getUserAddress` 方法时,我们使用了 `thenAnswer` 方法来自定义方法的行为。在该方法中,我们获取了 `getUserAddress` 方法的参数,并使用 `addressService` 来获取用户的地址。最后,我们返回了模拟的地址对象。 接下来,我们使用 `when` 方法来模拟 `getAddress` 方法的调用。在模拟 `getAddress` 方法时,我们使用了 `thenReturn` 方法来指定方法的返回值。 通过这种方式,我们可以模拟多层调用的方法并指定它们的行为。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值