Я разрабатываю фреймворк в iOS, который делает HTTP-вызовы на сервер. Я хотел написать модульный тест для тестирования API. Я хотел издеваться над вызовами сервера, фактически не выполняя вызов сервера. делает издевательские вызовы сервера. Как нам установить ожидания и вернуть созданный вручную ответ URL-адреса. Я использую структуру XCTest для модульного тестирования и OCMock для имитации объектов.
Макет NSHTTPURLRequest и NSHTTPURLResponse в модульном тесте iOS
Ответы (2)
Вот как можно имитировать sendAsynchronousRequest:
NSDictionary *serverResponse = @{ @"response" : [[NSHTTPURLResponse alloc] initWithURL:nil statusCode:200 HTTPVersion:nil headerFields:@{}],
@"data" : [@"SOMEDATA" dataUsingEncoding:NSUTF8StringEncoding]
};
id connectionMock = [OCMockObject mockForClass:NSURLConnection.class];
[[[connectionMock expect] andDo:^(NSInvocation *invocation) {
void (^handler)(NSURLResponse*, NSData*, NSError*);
handler = [invocation getArgumentAtIndexAsObject:4];
handler(serverResponse[@"response"], serverResponse[@"data"], serverResponse[@"error"]);
}] sendAsynchronousRequest:OCMOCK_ANY queue:OCMOCK_ANY completionHandler:OCMOCK_ANY];
ИЗМЕНИТЬ
Чтобы внести ясность, вот что происходит. В этом примере наш реальный код вызывает [NSURLConnection sendAsynchronousRequest: queue: completionHandler:]
. В этот метод передаются три аргумента плюс дополнительные _cmd
и self
, которые передаются всем вызовам методов Objective-C. Таким образом, когда мы проверяем наш NSInvocation
, аргумент с индексом 4 является нашим обработчиком завершения. Поскольку мы моделируем ответ сервера, мы хотим вызвать этот обработчик с поддельными данными, которые представляют тестируемый нами случай.
Сигнатура для вызова метода getArgumentAtIndexAsObject
находится в заголовочном файле, включенном в OCMock, но по умолчанию не включена в платформу. Кажется, это называется NSInvocation+OCMAdditions.h
. Это упрощает получение аргументов вызова, возвращая id
.
Используйте OHTTPStubs, https://github.com/AliSoftware/OHHTTPStubs.
Вот практический пример имитации ответа на конкретный запрос GET и возврата данных JSON.
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
return [request.URL.path isEqualToString:@"/api/widget"];
} withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
id JSON = @{ @"id": @"1234", @"name" : @"gadget" };
NSData *data = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:nil];
return [OHHTTPStubsResponse responseWithData:data statusCode:200 headers:@{ @"Content-Type": @"application/json" }];
}];