使用OCMockito验证方法调用

Bac*_*ach 2 unit-testing ios ocmockito ochamcrest

我在ClassA中有这两种方法

-(IBAction)onSubmit;
-(void)validateName:(NSString*)name;
Run Code Online (Sandbox Code Playgroud)

@implementation

- (IBAction)onSubmit {
    [self validateName:self.textfield.text];
}

-(void)validateName:(NSString*)name{
    // do something
}
Run Code Online (Sandbox Code Playgroud)

我的测试如下所示:

//given
ClassA *classA = mock([ClassA class]);
classA.textfield.text = @"Foo";

// when 
[classA onSubmit];

[verify(classA) validateName:@"Foo"];
Run Code Online (Sandbox Code Playgroud)

但这不起作用,我一直在:

Expected 1 matching invocation, but received 0
Run Code Online (Sandbox Code Playgroud)

在调用onSubmit时,如何编写验证validateName是否已执行的测试.

End*_*ker 5

适当的单元测试测试内部状态和外部行为.单元测试是测试是否你的代码做一些事情,而不是怎么它做一些事情.状态验证会告诉您实现了预期的结果,而行为验证则告诉您协作对象正确地与您正在测试的系统进行交互.这可以让你做一些精彩的事情,比如重构.

对内部状态的测试如下:

给定初始状态,如果被测系统做了某些事情,那么 结果状态应该是这个.

对外部行为的测试如下:

如果被测系统做了什么,那么另一个单位应该做其他事情.

第一种测试是通过标准断言完成的(assertThat()在OCHamcrest的情况下调用).第二种测试(正确地)通过验证测试双精度(verify()在OCMockito的情况下调用)来完成.

模拟被测系统是没有任何意义的.如果您发现有必要测试内部行为(即被测系统调用的特定方法),那么您需要将这些行为映射到状态.在您的情况下,这意味着ClassA实现了一个标志,如BOOL nameValidated(最好使用getter isNameValidated)或变量,如NSString*validatedName.