Fabrizio Bartolomucci
Fabrizio Bartolomucci

Reputation: 4958

waitForExpectationsWithTimeout crashes

I am trying to test an asynchronous request with XCTest and so using expectationWithDescription:. Yet when waitForExpectationsWithTimeout is called it immediately crashes without even waiting for the timeout. I even tried putting the fulfill operation soon after just to exclude a timeout issue, but it di no change things; this is my function:

func testTrafficRefresh(){
    let expectation = expectationWithDescription("refreshed")
    waitForExpectationsWithTimeout(10, handler:nil)
    traffic.trafficRefresh {[weak self] () -> Void in
        let coming=inArrivoHDDetailViewController.sharedDetailController().activeTransit
        let buses=self!.traffic.arrivingBuses
        let count=buses.count
        XCTAssert(count==0 && coming==0, "No buses and active transit")
        XCTAssert(count>0 && coming==1, "Arriving buses and inactive transit")
        expectation.fulfill()   
    }
}

The same behavior happens in other functions. If I take away the waitForExpectationsWithTimeout operation and keep the expectationWithDescription operation, it crashes at the end of the function. In both case the crash repot is the following:

libsystem_kernel.dylib`__pthread_kill:
0x10723227c <+0>:  movl   $0x2000148, %eax
0x107232281 <+5>:  movq   %rcx, %r10
0x107232284 <+8>:  syscall 
0x107232286 <+10>: jae    0x107232290               ; <+20>
0x107232288 <+12>: movq   %rax, %rdi
0x10723228b <+15>: jmp    0x10722dc53               ; cerror_nocancel
0x107232290 <+20>: retq   
0x107232291 <+21>: nop    
0x107232292 <+22>: nop    
0x107232293 <+23>: nop

Upvotes: 1

Views: 2605

Answers (2)

Fabrizio Bartolomucci
Fabrizio Bartolomucci

Reputation: 4958

I watched the specific talk in WWDC14 and came out with the following implementation:

 func testTrafficRefresh(){
    let expectation = expectationWithDescription("refreshed")
    traffic.trafficRefresh {[weak self] () -> Void in
        let coming=inArrivoHDDetailViewController.sharedDetailController().activeTransit
        let buses=self!.traffic.arrivingBuses
        let count=buses.count
        XCTAssert(((count == 0 && coming==1)||(count>0 && coming==1)), "Transit status \(coming) not corresponding to arriving buses \(count)")
        expectation.fulfill()
    }
    waitForExpectationsWithTimeout(20, handler:nil)
}

it is very similar to the original one but for the position of the waitForExpectationsWithTimeout command, that seems to be crucial.

Upvotes: 2

hris.to
hris.to

Reputation: 6363

You can try to provide implementation for the handler. As per docs handler parameter is not optional in waitForExpectationsWithTimeout markup:

func waitForExpectationsWithTimeout(timeout: NSTimeInterval, handler handlerOrNil: XCWaitCompletionHandler!)

Therefore you can try to provide explicity unwrapped handler(even empty one will do the job):

    waitForExpectationsWithTimeout(10) { error in
        //XCTAssertNil(error, "") this is optional
    }

Also you could try to follow this post and see whether you get more appropriate crash log.

Upvotes: 3

Related Questions