Модульные Тесты AFNetworking
Я пытаюсь выполнить модульный тест, используя приведенный ниже код. Однако тест просто зависает на участке ожидания. Ниже приведен мой тестовый код. Я новичок в iOS и AFNetworking. Любая помощь будет оценена по достоинству.
Вещи, Которые Я Знаю.: Вызывается метод в USAPIConnection. На TestController не вызывается метод success или failure. Запрос к API rails работает. (Я знаю, что он возвращает код 200 OK).
Вещи, которых я не знаю.: Является ли AFHTTPRequestOperationManager действительно отправляете запрос? Почему нет ни одного успешного метода отказа, который был бы послан? Должен ли этот модульный тест быть достаточным для тестирования?
XCTest Код
#import <XCTest/XCTest.h>
#import "USAPIConnection.h"
#import "Controller.h"
@interface TestController : NSObject <Controller>
@property bool done;
@end
@implementation TestController
-(void)asynchronousSuccessfulWithObject:(id)object type:(int)type{
NSLog(@"Object: %@", object);
XCTAssertNotNil(object,"@Should have returned JSON object: %s",__PRETTY_FUNCTION__);
_done = true;
}
-(void)asynchronousUnsuccessfulWithError:(NSError *)error type:(int)type{
XCTFail(@"Unsuccessful async call with error%s: %s",error,__PRETTY_FUNCTION__);
_done = true;
}
@end
@interface USAPIConnectionTests : XCTestCase
@end
@implementation USAPIConnectionTests
- (void)setUp
{
[super setUp];
NSLog(@"Beginning Test: %s",__PRETTY_FUNCTION__);
}
- (void)tearDown
{
NSLog(@"Ending Test: %s",__PRETTY_FUNCTION__);
[super tearDown];
}
- (void)testGetTeamById
{
TestController* testController = [[TestController alloc] init];
testController.done = false;
[USAPIConnection getTeamById:1 controller:testController];
int count = 0;
while(!testController.done && count < 10){
//Waiting
[NSThread sleepForTimeInterval:3.0];
count = count + 1;
}
if(count == 10){
XCTFail(@"Timed out: %s",__PRETTY_FUNCTION__);
}
}
@end
Метод, вызываемый в USAPIConnection
+(void)getTeamById:(int)identity controller:(id<Controller>)controller{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFJSONResponseSerializer* serializer = [AFJSONResponseSerializer serializer];
serializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
manager.responseSerializer = serializer;
[manager POST:[NSString stringWithFormat:@"http://%@/team/%D",baseURL,identity] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[controller asynchronousSuccessfulWithObject:responseObject type:TYPETEAMSBYNAME];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[controller asynchronousUnsuccessfulWithError:error type:TYPETEAMSBYNAME];
}];
}
Попытки
Попытка изменить метод испытания на следующий. Однако ни один NSLog в контроллере тестирования не работал.
- (void)testGetTeamById
{
TestController* testController = [[TestController alloc] init];
testController.done = false;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{[USAPIConnection getTeamById:1 controller:testController];});
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{NSLog(@"HELLO FROM ASYNC QUEUE");});
}
2 ответа:
XCTest в Xcode 6 (еще не выпущенном на момент написания статьи) поддерживает тестирование асинхронных методов.
Вот небольшой фрагмент в Swift, который показывает, как это может выглядеть:
Предположим, что у вас есть асинхронный метод с функцией завершения в качестве параметра:
func doSomethingAsync(completion:(result: Int?, error: Int?) -> ())
Теперь вы хотите проверить, успешно ли выполняется эта асинхронная функция, или вы хотите проверить некоторый код, который вы определяете в продолжении (обработчике завершения):
func testAsyncFunction() { let expect = self.expectationWithDescription("completion handler called") doSomethingAsync { (result, error) -> () in if let value = result? { println("Result: \(value)") } else { println("Error: \(error!)") } expect.fulfill() } waitForExpectationsWithTimeout(1000, handler: nil) }
Вы можете читать подробнее о новых методах XCTest
self.expectationWithDescription:
fulfill
иwaitForExpectationsWithTimeout:
в заголовках XCTest.Я сейчас занимаюсь модульным тестированием с помощью этой новой асинхронной тестовой установки. Просто отсутствует некоторая функциональность, например, наличие метода
reject
наряду сfulfill
с необязательным строковым параметром для ведения журнала. ИМО, это выглядит довольно привлекательным, и это работает отлично до сих пор. Итак, я действительно призываю вас заглянуть в бета-версию Xcode;Тем временем, вы можете найти библиотеку "promise", применимую к реализовать тестирование асинхронных методов. Я предложил использовать библиотеку RXPromise (я автор) для модульного тестирования несколько раз на этом форуме. ;)