42

So Apple said in the release note of Xcode 6 that we can now do asynchronous testing directly with XCTest.

Anyone knows how to do it using Xcode 6 Beta 3 (Using objective-C or Swift)? I don't want the known semaphore method, but the new Apple way.

I searched into the released note and more but I found nothing. The XCTest header is not very explicit either.

Dimillian
  • 3,616
  • 4
  • 33
  • 53

4 Answers4

68

Obj-C example:

- (void)testAsyncMethod
{

    //Expectation
    XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method Works!"];

    [MyClass asyncMethodWithCompletionBlock:^(NSError *error, NSHTTPURLResponse *httpResponse, NSData *data) {

        if(error)
        {
            NSLog(@"error is: %@", error);
        }else{
            NSInteger statusCode = [httpResponse statusCode];
            XCTAssertEqual(statusCode, 200);
            [expectation fulfill];
        }

    }];


    [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) {

        if(error)
        {
            XCTFail(@"Expectation Failed with error: %@", error);
        }

    }];
}
jonbauer
  • 946
  • 1
  • 7
  • 12
  • 5
    silly question: what if my `asyncMethod` doesn´t have a completion block? I have no idea how to test this. – 最白目 Nov 17 '15 at 14:47
  • 1
    Assuming you run it on a dispatch_queue, you can schedule your test on the same queue after you started the work you were planning on doing. Just dispatch_async onto the same queue and then in that continuation block do what you need to – Bob9630 Mar 08 '16 at 20:33
52

The sessions video is perfect, basically you want to do something like this

func testFetchNews() {
    let expectation = self.expectationWithDescription("fetch posts")

    Post.fetch(.Top, completion: {(posts: [Post]!, error: Fetcher.ResponseError!) in
        XCTAssert(true, "Pass")
        expectation.fulfill()
    })

    self.waitForExpectationsWithTimeout(5.0, handler: nil)
}
onmyway133
  • 45,645
  • 31
  • 257
  • 263
Dimillian
  • 3,616
  • 4
  • 33
  • 53
11

Session 414 covers async testing in Xcode6

https://developer.apple.com/videos/wwdc/2014/#414

mittens
  • 756
  • 6
  • 9
1

How I did in swift2

Step 1: define expectation

let expectation = self.expectationWithDescription("get result bla bla")

Step 2: tell the test to fulfill expectation right below where you capture response

responseThatIGotFromAsyncRequest = response.result.value
expectation.fulfill()

Step 3: Tell the test to wait till the expectation is fulfilled

waitForExpectationsWithTimeout(10)

STep 4: make assertion after async call is finished

XCTAssertEqual(responseThatIGotFromAsyncRequest, expectedResponse)
Ankit Vij
  • 274
  • 3
  • 12