gpt4 book ai didi

ios - 如何使用返回数据的完成处理程序为方法编写单元测试?

转载 作者:行者123 更新时间:2023-11-28 20:52:40 25 4
gpt4 key购买 nike

我一直在尝试弄清楚如何使用 OCMock 为这种方法编写单元测试。有人可以帮我吗?

- (void)executeRequest:(NSURLRequest *)request withCompletionHandler:(void (^)(id responseData, NSError *error))completionHandler
{
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error)
{
NSLog(@"Network error occurred: %@", [error localizedDescription]);
dispatch_async(dispatch_get_main_queue(), ^(void) { completionHandler(nil, error);
});
return;
}
if ([response isKindOfClass:NSHTTPURLResponse.class])
{
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200)
{
NSLog(@"Network error occurred. Status code: %ld", (long)statusCode);
return;
}
}
completionHandler(data, nil);
}];
[dataTask resume];
}

最佳答案

您应该将 OCMArg 与 checkWithBlock 或 invokeBlockWithArgs 结合使用来测试完成处理程序。举个例子:

  1. 通过单击 command+N 创建 XCTestCase 子类:

New_file

  1. 为可测试实例和必要的模拟添加属性:

    @interface SomeClassTests : XCTestCase

    @property (nonatomic, strong) SomeClass *testableInstance;
    @property (nonatomic, strong) NSURLSession *mockSession;
    @property (nonatomic, strong) NSURLRequest *mockRequest;
    @property (nonatomic, strong) NSHTTPURLResponse *mockResponse;

    @end
  2. 设置属性:

    - (void)setUp
    {
    [super setUp];
    self.testableInstance = [SomeClass new];
    self.mockSession = OCMClassMock([NSURLSession class]);
    self.mockRequest = OCMClassMock([NSURLRequest class]);
    self.mockResponse = OCMClassMock([NSHTTPURLResponse class]);
    OCMStub(ClassMethod([(id)self.mockSession sharedSession])).andReturn(self.mockSession);
    }
  3. 不要忘记在拆卸时清理:

    - (void)tearDown
    {
    [(id)self.mockSession stopMocking];
    self.mockResponse = nil;
    self.mockRequest = nil;
    self.mockSession = nil;
    self.testableInstance = nil;
    [super tearDown];
    }
  4. 让我们测试发生错误时的情况:

    - (void)testWhenErrorOccuersThenCompletionWithSameError
    {
    // arrange
    NSError *givenError = [[NSError alloc] initWithDomain:@"Domain" code:0 userInfo:nil];
    OCMStub([self.mockSession dataTaskWithRequest:[OCMArg any] completionHandler:([OCMArg invokeBlockWithArgs:@"", self.mockResponse, givenError, nil])]);

    void (^givenCompletion)(id _Nonnull, NSError * _Nonnull) = ^void(id _Nonnull responseData, NSError * _Nonnull resultError) {
    // assert
    XCTAssertNil(responseData);
    XCTAssertEqual(resultError, givenError);
    };

    // act
    [self.testableInstance executeRequest:self.mockRequest withCompletionHandler:givenCompletion];
    }

因此我们将确保如果发生某些错误,则完成处理程序将在参数处调用并返回相同的错误。

  1. 让我们在收到一些错误状态代码时进行测试:

    - (void)testWhenBadStatusCodeThenReturnWithoutCompletion
    {
    // arrange
    OCMStub([self.mockResponse statusCode]).andReturn(403);
    OCMStub([self.mockSession dataTaskWithRequest:[OCMArg any] completionHandler:([OCMArg checkWithBlock:^BOOL(id param) {
    void (^passedCompletion)(NSData *data, NSURLResponse *response, NSError *error) = param;
    passedCompletion(nil, self.mockResponse, nil);
    return YES;
    }])]);

    void (^givenCompletion)(id _Nonnull, NSError * _Nonnull) = ^void(id _Nonnull responseData, NSError * _Nonnull resultError) {
    // assert
    XCTFail("Shouldn't be reached");
    };

    // act
    [self.testableInstance executeRequest:self.mockRequest withCompletionHandler:givenCompletion];
    }
  2. 最后让我们在实际获取数据时进行测试:

    - (void)testWhenSuccesThenCompletionWithSameData
    {
    // arrange
    NSData *givenData = [NSData data];
    OCMStub([self.mockResponse statusCode]).andReturn(200);
    OCMStub([self.mockSession dataTaskWithRequest:[OCMArg any] completionHandler:([OCMArg checkWithBlock:^BOOL(id param) {
    void (^passedCompletion)(NSData *data, NSURLResponse *response, NSError *error) = param;
    passedCompletion(givenData, self.mockResponse, nil);
    return YES;
    }])]);

    void (^givenCompletion)(id _Nonnull, NSError * _Nonnull) = ^void(id _Nonnull responseData, NSError * _Nonnull resultError) {
    // assert
    XCTAssertEqual(responseData, givenData);
    };

    // act
    [self.testableInstance executeRequest:self.mockRequest withCompletionHandler:givenCompletion];
    }

如果你打开一个覆盖,那么你会看到这样的测试完全覆盖了可测试的代码:

Coverage

关于ios - 如何使用返回数据的完成处理程序为方法编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56208069/

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