【问题标题】:Setting up delegate for NSURLSession and unit testing it为 NSURLSession 设置委托并对其进行单元测试
【发布时间】:2016-07-29 12:26:31
【问题描述】:

我目前正在尝试通过 NSURLSession 在异步 dataTaskWithRequest 上设置自定义委托。我已经设置了协议并实现了委托方法,但我一直在弄清楚我是否正确地实现了它,以及如何对其进行单元测试。具体来说,我想测试委托在调用后是否返回某些内容,并使用实时 API 调用进行测试。我已经尝试通过此处建议的方法 (OCUnit test for protocols/callbacks/delegate in Objective-C) 进行测试,但测试失败,可能是因为我遗漏了某些内容或没有考虑异步调用。尝试委托实现和单元测试的代码如下。

委托协议声明:

#include "PtvApiPublic.h"

#ifndef PtvApiDelegate_h
#define PtvApiDelegate_h

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

#endif /* PtvApiDelegate_h */

头文件:

#include "PtvApiDelegate.h"

#ifndef PtvApi_h
#define PtvApi_h

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

#endif /* PtvApi_h */

PtvApi.m 的片段

#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

【问题讨论】:

  • wrote a blog post 关于我如何测试 NSURLSession。也许这会有所帮助。
  • @dasdom 感谢您的链接,我会在重新设计我的其他 Swift 应用程序时参考它。

标签: ios objective-c unit-testing delegates nsurlsession


【解决方案1】:

好吧,我在 Apple 的 NSURLSession 文档和http://www.infinite-loop.dk/blog/2011/04/unittesting-asynchronous-network-access/ 的博客的帮助下自己弄清楚了。我现在已经使用实时 URL 对其进行了测试,当我将 API 模拟添加到我的单元测试并使单元测试更加健壮时,我将更新答案。

简而言之,NSURLSession 有自己的委托方法,在使用dataTaskWithRequest 的情况下,可以设置NSURLSessionDataDelegate 并用于检索API 结果。

委托声明的代码大部分是正确的,我只需要将头文件中的NSURLSessionDelegate更改为NSURLSessionDataDelegate即可。

单元测试需要一些设置,但其他方面非常简单。它涉及使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多