我有一个方法在模型中触发异步请求,并传递一个处理响应的块:
[user loginWithEmail:self.eMailTextField.text
andPassword:self.passwordTextField.text
block:^(UserLoginResponse response) {
switch (response) {
case UserLoginResponseSuccess:
{
// hooray
break;
}
case UserLoginResponseFailureAuthentication:
// bad credentials
break;
case UserLoginResponseFailureB:
// failure reason b
break;
default:
// unknown error
break;
}
}];
被调用方法为请求设置一些参数,并使用AFNetworking启动它。
现在我想编写一个单元测试,以确保调用类对每个可能的UserLoginResponse做出正确的反应。我正在使用Kiwi进行测试,但我认为这更像是一个普遍的问题......
我如何模拟从用户对象传递给块的参数? 我能想到的唯一方法是模拟底层请求并返回我期望的测试状态代码。还有更好的方法吗?
也可以使用委托来替换块,但我绝对更喜欢在这里使用块。
答案 0 :(得分:7)
这里似乎要验证两个不同的事情:1)用户对象将实际响应传递给块,2)块适当地处理各种响应代码。
对于#1,似乎正确的方法是模拟请求(该示例使用OCMock和Expecta语法):
[[[request expect] andReturn:UserLoginResponseSuccess] authenticate];
__block UserLoginResponse actual;
[user loginWithEmail:nil
andPassword:nil
block:^(UserLoginResponse expected) {
actual = expected;
}];
expect(actual).toEqual(UserLoginResponseSuccess);
对于#2,我创建了一个返回要验证的块的方法。然后你可以直接测试它而不需要所有其他依赖项:
在标题中:
typedef void(^AuthenticationHandlerBlock)(UserLoginResponse);
-(AuthenticationHandlerBlock)authenticationHandler;
在您的实施中:
-(AuthenticationHandlerBlock)authenticationHandler {
return ^(UserLoginResponse response) {
switch (response) {
case UserLoginResponseSuccess:
{
// hooray
break;
}
case UserLoginResponseFailureAuthentication:
// bad credentials
break;
case UserLoginResponseFailureB:
// failure reason b
break;
default:
// unknown error
break;
}
}
}
在你的测试中:
AuthenticationHandlerBlock block = [user authenticationHandler];
block(UserLoginResponseSuccess);
// verify success outcome
block(UserLoginResponseFailureAuthentication);
// verify failure outcome
block(UserLoginResponseFailureB);
// verify failure B outcome
答案 1 :(得分:2)
对于那些在回答这个问题2年多后回答这个问题的读者,Kiwi现在支持嘲笑v2.2中的这些类方法。由于OP使用的是Kiwi,我觉得它比接受的答案要清晰得多......