gpt4 book ai didi

ios - 为 NSURLSession 设置委托(delegate)并对其进行单元测试

转载 作者:行者123 更新时间:2023-11-29 01:05:08 25 4
gpt4 key购买 nike

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

委托(delegate)协议(protocol)声明:

#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

最佳答案

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

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

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

单元测试需要一些设置,但在其他方面非常简单。它涉及使用 NSURLSession 调用初始化类,将对象的委托(delegate)设置为 self,并将标志变量初始化为 NO。调用委托(delegate)时,标志变量将设置为 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

关于ios - 为 NSURLSession 设置委托(delegate)并对其进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36496232/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com