2016-04-08 11 views
0

現在NSURLSession経由で非同期のdataTaskWithRequestにカスタムデリゲートを設定しようとしています。プロトコルを設定してデリゲートメソッドを実装しましたが、正しく実装したかどうか、単体テストを行う方法はわかりません。具体的には、呼び出された後にデリゲートが何かを返すかどうかをテストし、ライブAPI呼び出しでテストしたいと思います。私はここで提案されたアプローチ(OCUnit test for protocols/callbacks/delegate in Objective-C)でテストを試みましたが、テストが失敗しました。これは、おそらく何かが欠落しているか、非同期呼び出しを考慮していないためです。試行されたデリゲートの実装とユニットテストのコードは次のとおりです。NSURLSessionのデリゲートの設定とユニットテスト

委任プロトコル宣言:

#include "PtvApiPublic.h" 

#ifndef PtvApiDelegate_h 
#define PtvApiDelegate_h 

@class PtvApi; 
@protocol PtvApiDelegate <NSObject> 
    -(void) ptvApiHealthCheck: (PtvApi *) sender; 
@end 

#endif /* PtvApiDelegate_h */ 

ヘッダファイル:PtvApi.m

#include "PtvApiDelegate.h" 

#ifndef PtvApi_h 
#define PtvApi_h 

@interface PtvApi : NSObject 
@property (nonatomic, weak) id <NSURLSessionDelegate> delegate; 
- (void)ptvApiHealthCheck; 
@end 

#endif /* PtvApi_h */ 

スニペット

#import <Foundation/Foundation.h> 
#import <CommonCrypto/CommonHMAC.h> 
#import <CommonCrypto/CommonDigest.h> 
#import "PtvApiPublic.h" 
#import "PtvApiPrivate.h" 
#import "PtvApiDelegate.h" 

@implementation PtvApi 
@synthesize delegate; 

... 

- (void)ptvApiHealthCheck 
{ 
    NSString *fullUrl = [self GenerateRequestUrl]; 

    NSURLSession *apiSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:delegate delegateQueue:nil]; 
    NSURL *apiUrl = [NSURL URLWithString: fullUrl]; 
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:apiUrl]; 
    [apiSession dataTaskWithRequest:urlRequest]; 
} 

@end 

ユニットテスト:

#import <XCTest/XCTest.h> 

#import "PtvApiPublic.h" 

@interface APIDelegateTests : XCTestCase <NSURLSessionDelegate> 
{ 
    PtvApi *testApi; 
    BOOL callbackInvoked; 
} 
@end 

@implementation APIDelegateTests 

- (void)setUp { 
    [super setUp]; 
    testApi = [[PtvApi alloc] init]; 
    testApi.delegate = self; 
} 

- (void)tearDown { 
    testApi.delegate = nil; 
    [super tearDown]; 
} 

- (void)testThatApiCallbackWorks { 
    [testApi ptvApiHealthCheck]; 

    XCTAssert(callbackInvoked, @"Delegate should return something, I think..."); 
} 
@end 
+1

私はNSURLSessionをテストする方法について(http://swiftandpainless.com/an-easy-way-to-stub-nsurlsession/)[ブログ記事を書いています]。たぶんこれが役立ちます。 – dasdom

+0

@dasdomリンクをありがとう、私は私の他のスウィフトアプリをリエンジニアリングするときにそれを参照します。 –

答えて

1

申し訳ありません.AppleのNSURLSessionのドキュメントとhttp://www.infinite-loop.dk/blog/2011/04/unittesting-asynchronous-network-access/のブログの助けを借りて、自分で考え出しました。私は現時点でURLを使ってテストしましたが、単体テストにAPIを追加すると答えが更新され、単体テストがより堅牢になります。

NSURLSessionには独自の代理メソッドがあり、この場合はdataTaskWithRequestが使用されます。NSURLSessionDataDelegateを設定してAPI結果を取得できます。

デリゲート宣言のコードはほとんど正しいので、ヘッダーファイルのNSURLSessionDelegateNSURLSessionDataDelegateに変更するだけでした。

単体テストには多少のセットアップが必要ですが、そうでなければかなり簡単です。 NSURLSessionコールでクラスを初期化し、オブジェクトの代理人をselfに設定し、フラグ変数をNOに初期化します。デリゲートが呼び出されると、フラグ変数はYESに設定されます。これは最初にテストしています。完全にセットアップされた単体テストは以下の通りです。

@interface APIDelegateTests : XCTestCase <NSURLSessionDataDelegate> 
{ 
    PtvApi *testApi; 
    BOOL callbackInvoked; 
} 
@end 

@implementation APIDelegateTests 

- (void)setUp { 
    [super setUp]; 
    testApi = [[PtvApi alloc] init]; 
    testApi.delegate = self; 
    callbackInvoked = NO; 
} 

- (void)tearDown { 
    testApi.delegate = nil; 
    [super tearDown]; 
} 

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data 
{ 
    callbackInvoked = YES; 
} 

// Method is credit to Claus Brooch. 
// Retrieved from http://www.infinite-loop.dk/blog/2011/04/unittesting-asynchronous-network-access/ on 10/04/2016 
- (BOOL)waitForCompletion:(NSTimeInterval)timeoutSecs { 
    NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeoutSecs]; 

    do { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:timeoutDate]; 
     if([timeoutDate timeIntervalSinceNow] < 0.0) 
      break; 
    } while (!callbackInvoked); 

    return callbackInvoked; 
} 

- (void)testThatApiCallbackWorks { 
    [testApi ptvApiHealthCheck]; 

    XCTAssert([self waitForCompletion:30.0], @"Testing to see what happens here..."); 
} 
@end 
関連する問題