使用 OCMockito 验证方法调用
Posted
技术标签:
【中文标题】使用 OCMockito 验证方法调用【英文标题】:Verify method call with OCMockito 【发布时间】:2013-03-28 19:34:53 【问题描述】:我在 ClassA 中有这两种方法
-(IBAction)onSubmit;
-(void)validateName:(NSString*)name;
@实现
- (IBAction)onSubmit
[self validateName:self.textfield.text];
-(void)validateName:(NSString*)name
// do something
我的测试如下所示:
//given
ClassA *classA = mock([ClassA class]);
classA.textfield.text = @"Foo";
// when
[classA onSubmit];
[verify(classA) validateName:@"Foo"];
但这不起作用,我不断收到:
Expected 1 matching invocation, but received 0
当 onSubmit 被调用时,我如何编写一个测试来验证 validateName 是否被执行。
【问题讨论】:
【参考方案1】:适当的单元测试测试内部状态和外部行为。您的单元测试是在测试是否您的代码做某事,而不是 如何它做某事。状态验证告诉您达到了预期的结果,而行为验证告诉您协作对象正确地与被测系统交互。这让你可以做一些很棒的事情,比如重构。
内部状态测试如下:
给定一个初始状态,如果被测系统做了某事,那么 结果状态应该是this。
外部行为测试如下:
如果被测系统做某事,那么另一个单元应该做其他事情。
第一类测试是通过标准断言完成的(在 OCHamcrest 的情况下是assertThat()
调用)。第二种测试(正确)通过验证测试替身(在 OCMockito 的情况下调用verify()
)来完成。
模拟被测系统没有任何意义。如果您发现有必要测试内部行为(即被测系统调用的特定方法),那么您需要将这些行为映射到状态。在您的情况下,这意味着 ClassA 实现了一个标志,例如 BOOL nameValidated(最好使用 getter isNameValidated)或一个变量,例如 NSString *validatedName.
【讨论】:
以上是关于使用 OCMockito 验证方法调用的主要内容,如果未能解决你的问题,请参考以下文章
OCMockito / OCHamcrest 验证数组包含对象属性