objective-c - 如何将 block 的结果模拟为方法参数?

标签 objective-c ios unit-testing mocking

我有一个方法可以触发模型中的异步请求并传递一个处理响应的 block :

[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 做出正确的 react 。我正在使用 Kiwi 进行测试,但我认为这是一个更普遍的问题......

我如何模拟从用户对象传递到 block 的参数? 我能想到的唯一方法是模拟底层请求并返回我期望用于测试的状态代码。有没有更好的办法?

也可以使用委托(delegate)来替换 block ,但我绝对更喜欢在这里使用 block 。

最佳答案

您似乎需要在此处验证 2 件不同的事情:1) 用户对象将实际响应传递给 block ,以及 2) block 适本地处理各种响应代码。

对于 #1,似乎正确的方法是模拟请求(该示例使用 OCMockExpecta 语法):

[[[request expect] andReturn:UserLoginResponseSuccess] authenticate];

__block UserLoginResponse actual;

[user loginWithEmail:nil
         andPassword:nil
               block:^(UserLoginResponse expected) {
                   actual = expected;
               }];

expect(actual).toEqual(UserLoginResponseSuccess);

对于 #2,我将创建一个方法来返回您要验证的 block 。然后你可以直接测试它而不需要所有其他依赖项:

在你的标题中:

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

关于objective-c - 如何将 block 的结果模拟为方法参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8148938/

相关文章:

ios - 使用 Swift 3 解析 JSON 响应

ios - Xcode 11 : Changes in code not updated to app or breakpoint doesn't work

java - 使用 Ant 运行 Powermock 套件会导致 ClassCastExceptions

python - Django : Testing admin user

objective-c - 值插入模拟器但未显示在数据库表中

objective-c - 为什么我应该避免在 -finalize 中做严肃的工作?

iphone - 如何检测在 UISearchDisplayController 中点击灰色(变暗)背景

ios - 如何将字典插入数组

ios - IOS 8 中的预处理器宏和 bool 值未正确评估

java - 在参数化 JUnit 4+ 测试中测试可选异常