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");});
}
source to share
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.;)
source to share