IOS -NSRunLoop in XCTest: how do I get a startup loop to work in Unit Test?

OK I looked around and did not find the exact answer to my question.

I am trying to check the timeout handler in unit test (and not on the main run).

The problem is that [NSRunLoop mainRunLoop] does not work in unit tests the same way as in standard Run.

I do my timeouts this way:

 NSTimer *pTimeoutHandler = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timeoutHandler:) userInfo:nil repeats:NO ]; [[NSRunLoop mainRunLoop] addTimer:pTimeoutHandler forMode:NSRunLoopCommonModes]; 

This works in a standard run. This is the recommended timeout setting.

However, in a test run, this does not work. The timeoutHandler:(NSTimer*)timer procedure is never called.

Something seems to be interfering with the startup cycle.

Is there a way to make the timeout work in both run and unit test?

+7
ios unit-testing
source share
2 answers

When using timers and the main runloop, you need to manually run runloop:

 while (continueCondition || !time_way_over_timeout) { [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } 

where continueCondition may be some flag indicating that the timeout handler has been called, and time_way_over_timeout comparing the current time with the predefined maximum execution time (so that you can handle the "time test timeout" for your unit test ^^)

Also see this blog post about asynchronous unit testing: http://dadabeatnik.wordpress.com/2013/09/12/xcode-and-asynchronous-unit-testing/

+10
source share

It looks something like this in Swift 3.0 using XCTest.

 // somebody has to call the .fulfill() method on this variable // to the expectation will fail after 25 seconds var asyncExpectation : XCTestExpectation! func testExample() { asyncExpectation = expectation(description: "longRunningFunction") self.waitForExpectations(timeout: 25.0) { (error) in if let error = error { print("Error \(error)") } } // more stuff here } 
+1
source share

All Articles