Tests for AFNetworking networks

I am trying to unit test with the below code. However, the test just hangs in the waiting part. My test code is below. I am new to iOS and AFNetworking. Any help would be appreciated.

Things I know: A method is called in USAPIConnection. The TestController method failed or failed. The rails api request works. (I know it returns 200 OK code).

Things I don't know: Is the AFHTTPRequestOperationManager actually sending the request? Why can't I send the opt-out method? Should this unit test be sufficient for testing purposes?

XCTest code

#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

      

Method called in 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];
    }];
}

      

Attempts

Trying to change the testing method to below. However, no NSLog in the test controller started.

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

      

+3


source to share


2 answers


XCTest in Xcode 6 (not yet released at the time of writing) supports testing asynchronous methods.

Here's a small snippet in Swift that shows how this might look:

Suppose you have an asynchronous method with a completion function as a parameter:

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

      

Now you want to test if this async function succeeds or if you want to test the code you define in the continuation (completion handler):



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

      

You can read more about the new XCTest methods self.expectationWithDescription:

fulfill

and waitForExpectationsWithTimeout:

in the XCTest headers.

I am now testing unit testing with this new asynchronous testing tool. There is simply no functionality available for example. having a method reject

next to fulfill

an optional string parameter for logging. IMO it looks pretty attractive and it works great so far. So, I really recommend that you take a look at the beta of Xcode;

In the meantime, you can find the promise library useful for testing asynchronous method testing. I suggested using the RXPromise library (I am the author) for unit testing several times on this forum.;)

+3


source


To make an asynchronous call to UnitTest, you need something like a flag. This is discussed here:



How to unit test asynchronous APIs?

0


source







All Articles