Pruebas de la unidad AFNetworking

Estoy intentando probar la unidad usando el siguiente código. Sin embargo, la testing simplemente se cuelga en la parte de espera. Mi código de testing está debajo. Soy nuevo en iOS y AFNetworking. Cualquier ayuda sería apreciada.

Cosas que sé: se está llamando al método en USAPIConnection. No hay un método de éxito o falla llamado TestController. La request a los Rails api está funcionando. (Sé que devuelve un código 200 OK).

Cosas que no sé: ¿el AFHTTPRequestOperationManager realmente envía la request? ¿Por qué no se envía el método de falla? ¿Debería esta testing de unidad ser suficiente para la testing?

Código 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 

Método llamado en la connection USAPIC

 +(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]; }]; } 

Intentos

Intentar cambiar el método de testing al siguiente. Sin embargo, ni NSLog en el controller de testing se ejecutó.

 - (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");}); } 

XCTest en Xcode 6 (aún no publicado en el momento de la networkingacción) admite testings de methods asíncronos.

Aquí hay un pequeño fragment en Swift que muestra cómo puede verse:

Supongamos que tiene un método asíncrono con una function de finalización como parámetro:

 func doSomethingAsync(completion:(result: Int?, error: Int?) -> ()) 

Ahora, quiere probar si esta function asíncrona funciona correctamente o si desea probar algún código que defina en la continuación (el controller de finalización):

 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) } 

Puede leer más sobre los nuevos methods de XCTest self.expectationWithDescription: fulfill y waitForExpectationsWithTimeout: en los encabezados de XCTest.

Estoy haciendo testings de unidad por un time ahora con esta nueva installation de testing asíncrona. Simplemente falta alguna funcionalidad, por ejemplo, tener un método de reject junto con fulfill con un parámetro de cadena opcional para el logging. IMO, se ve bastante atractivo y funciona muy bien hasta ahora. Entonces, te animo a echar un vistazo a la Xcode beta;

Mientras tanto, puede encontrar una biblioteca "promise" aplicable para implementar testings de methods asíncronos. He sugerido utilizar la biblioteca RXPromise (soy el autor) para probar varias unidades en este foro. 😉

Para hacer una llamada asincrónica en UnitTest es necesario algo así como una bandera. Es mucho discutido aquí:

¿Cómo probar unidades API asíncronas?