Using XCTest, how can one chain together multiple discrete sequences of { expectations -> wait }?
Asked Answered
B

5

14

The documentation for XCTest waitForExpectationsWithTimeout:handler:, states that

Only one -waitForExpectationsWithTimeout:handler: can be active at any given time, but multiple discrete sequences of { expectations -> wait } can be chained together.

However, I have no idea how to implement this, nor can I find any examples. I'm working on a class that first needs to find all available serial ports, pick the correct port and then connect to the device attached to that port. So, I'm working with at least two expectations, XCTestExpectation *expectationAllAvailablePorts and *expectationConnectedToDevice. How would I chain those two?

Bulbous answered 19/3, 2015 at 16:44 Comment(0)
E
3

swift

let expectation1 = //your definition
let expectation2 = //your definition

let result = XCTWaiter().wait(for: [expectation1, expectation2], timeout: 10, enforceOrder: true)

if result == .completed {
    //all expectations completed in order
} 
Eberly answered 30/11, 2017 at 17:23 Comment(1)
The technique has finally caught up with the documentation. I've been been using this in Objective-C as well and it really works.Bulbous
F
7

I do the following and it works.

expectation = [self expectationWithDescription:@"Testing Async Method Works!"];

[AsynClass method:parameter callbackFunction:^(BOOL callbackStatus, NSMutableArray* array) {
    [expectation fulfil];
    // whatever
}];

[self waitForExpectationsWithTimeout:5 handler:^(NSError *error) {
    if (error) {
        XCTFail(@"Expectation Failed with error: %@", error);
    }
    NSLog(@"expectation wait until handler finished ");
}];

// do it again

expectation = [self expectationWithDescription:@"Testing Async Method Works!"];

[CallBackClass method:parameter callbackFunction:^(BOOL callbackStatus, NSMutableArray* array) {
    [expectation fulfil];
    // whatever
}];

[self waitForExpectationsWithTimeout:5 handler:^(NSError *error) {
    if (error) {
        XCTFail(@"Expectation Failed with error: %@", error);
    }
    NSLog(@"expectation wait until handler finished ");
}];
Flocculent answered 3/5, 2015 at 5:17 Comment(0)
E
3

swift

let expectation1 = //your definition
let expectation2 = //your definition

let result = XCTWaiter().wait(for: [expectation1, expectation2], timeout: 10, enforceOrder: true)

if result == .completed {
    //all expectations completed in order
} 
Eberly answered 30/11, 2017 at 17:23 Comment(1)
The technique has finally caught up with the documentation. I've been been using this in Objective-C as well and it really works.Bulbous
G
2

Assigning my expectation to a weak variable worked for me.

Grindelia answered 7/12, 2015 at 12:26 Comment(0)
C
0

This seems to be working for me in Swift 3.0 as well.

let spyDelegate = SpyDelegate()
var asyncExpectation = expectation(description: "firstExpectation")
spyDelegate.asyncExpectation = asyncExpectation
let testee = MyClassToTest(delegate: spyDelegate)
testee.myFunction() //asyncExpectation.fulfill() happens here, implemented in SpyDelegate

waitForExpectations(timeout: 30.0) { (error: Error?) in
    if let error = error {
        XCTFail("error: \(error)")
    }
}

asyncExpectation = expectation(description: "secoundExpectation")
spyDelegate.asyncExpectation = asyncExpectation
testee.delegate = spyDelegate
testee.myOtherFunction() //asyncExpectation.fulfill() happens here, implemented in SpyDelegate

waitForExpectations(timeout: 30.0) { (error: Error?) in
    if let error = error {
        XCTFail("error: \(error)")
    }
}
Cardwell answered 5/4, 2017 at 14:43 Comment(0)
B
0

Within a class that extends XCTestCase you can use wait(for:timeout:) like this:

let expectation1 = self.expectation(description: "expectation 1")
let expectation2 = self.expectation(description: "expectation 2")
let expectation3 = self.expectation(description: "expectation 3")
let expectation4 = self.expectation(description: "expectation 4")

// ...
// Do some asyc stuff, call expectation.fulfill() on each of the above expectations.
// ...

wait(for:[expectation1,expectation2,expectation3,expectation4], timeout: 8)

Blatant answered 8/8, 2020 at 19:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.