How to test Swift asynchronous methods

I have the following class that I want to run from unions:

class WmBuildGroupsTask{

init(){}

    func doInBackground() -> WmTransferItem{
         NSThread.sleepForTimeInterval(20)// sleep 20 sec to simulate long task
                            }

    func onPostExecute(transferItem:WmTransferItem){        
        //called when long task finished        
    }


    func execute(){        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

            var  transItem:WmTransferItem = self.doInBackground()

            dispatch_async(dispatch_get_main_queue(), {
                self.onPostExecute(transItem)
                });
            });                
      }    
}

I tried to run the Unitest file:

var task:WmBuildGroupsTask = WmBuildGroupsTask()
task.execute(); 

but the test runs until the method completes doInBackground().

How to make it work?

+4
source share
1 answer

You can achieve this using XCTestExpectation (with Xcode 6) .

How it works:

We create an instance XCTestExpectationthat works like a timer. Your test will never end until one of two cases occurs:

  • XCTestExpectation.fulfill() called
  • you have a timeout defined using waitForExpectationsWithTimeout, and therefore the test will fail

How to use XCTestExpectation

Step 1

( WmBuildGroupsTask):

protocol MyCallback{
    func onDone(results: String)
}

.

2

Unitest :

class Test_WmBuildGroupsTask : XCTestCase, MyCallback {
/* ...*/    
}

3

XCTestExpectation ( Test_WmBuildGroupsTask):

var theExpectation:XCTestExpectation?

onDone():

func onDone(results: String){

    theExpectation?.fulfill() // it will release our "timer"
}

4

:

func test___WmBuildGroupsTask() {

    // Declare  expectation
     theExpectation = expectationWithDescription("initialized") // dummy text

    var task:WmBuildGroupsTask = WmBuildGroupsTask()
    task.delegate = self // pass delegate to WmBuildGroupsTask class        
    task.execute();


    // Loop until the expectation is fulfilled in onDone method
    waitForExpectationsWithTimeout(500, { error in XCTAssertNil(error, "Oh, we got timeout")
    })
}// end func

, WmBuildGroupsTask:

5

:

var delegate:MyCallback?

onPostExecute :

func onPostExecute(transferItem:WmTransferItem){
   /* .. */

   delegate?.onDone("finished")// call callback        
}

.

()

+12

All Articles