2011-11-16 77 views
2

我有觸發模型中的異步請求,並將該處理的響應的塊的方法:如何模擬塊的結果作爲方法參數?

[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進行測試,但我認爲這是一個更普遍的問題...

我該如何模擬從用戶對象傳遞給塊的參數? 我能想到的唯一方法是嘲笑底層請求並返回我期望用於測試的狀態碼。有沒有更好的辦法?

它也可以通過使用委託來替換塊,但我肯定會更喜歡在這裏使用塊。

回答

7

看起來好像你想在這裏驗證2個不同的東西:1)用戶對象將實際的響應傳遞給塊,2)塊適當地處理各種響應代碼。

對於#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,我會創建一個返回的塊的方法你想驗證。然後你就可以不用其他所有依賴直接測試:

在您的標題:

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 
+0

謝謝,這真的幫了很多!我已經把' - (AuthenticationHandlerBlock)authenticationHandler;'放在我的ViewController中調用用戶登錄。唯一的缺點是我有一個新的公開方法。 原來的方法現在只是調用處理響應的'AuthenticationHandlerBlock'。 – tim

+1

如果您不希望它公開,則不必將其放在標題中。您可以在.m文件頂部的類別中聲明它。您只需要將該類別複製到您的測試課程中,以避免警告。 –

2

對於那些讀者在回答2年後才提出這個問題,現在獼猴桃支持嘲笑這些從v2.2開始的各種類方法。由於OP使用獼猴桃,我認爲這是一個比接受的答案乾淨得多:)

看看https://github.com/allending/Kiwi/issues/200的細節。

相關問題