When writing a certain asynchronous test using XCTest and XCTestExpectation I would like to assert that a certain block was not executed. The following code is successful in asserting that a block was executed and if not the test fails.
#import <XCTest/XCTest.h>
#import "Example.h"
@interface Example_Test : XCTestCase
@property (nonatomic) Example *example;
@end
@implementation Example_Test
- (void)setUp {
[super setUp];
}
- (void)tearDown {
[super tearDown];
}
- (void)testExampleWithCompletion {
self.example = [[Example alloc] init];
XCTestExpectation *expectation = [self expectationWithDescription:@"expection needs to be fulfilled"];
[self.example exampleWithCompletion:^{
[expectation fulfill]
}];
[self waitForExpectationsWithTimeout:2.0 handler:^(NSError *error) {
if (error) {
NSLog(@"Timeout Error: %@", error);
}
}];
}
There doesn't seem to be an obvious way to execute this the other way around; where the test succeeds if the block did not execute after the timeout and fails if it executed before the timeout. Adding to this, I would like to assert that the block executed at a later time when a different condition is met.
Is there a straightforward way to do this with XCTestExpectation or will I have to create a workaround?
I know this is a couple years old, but I just stumbled across a parameter on XCTestExpectation that lets you invert the expectation. Hopefully this will help someone else stumbling across this. Answer is in Swift
let expectation = XCTestExpectation(description: "")
expectation.isInverted = true
Documentation: https://developer.apple.com/documentation/xctest/xctestexpectation/2806573-isinverted
You can achieve this with a dispatch_after
call that is scheduled to run just before your timeout. Use a BOOL
to record if the block has executed, and an assertion to pass or fail the test once the expectation is completed.
- (void)testExampleWithCompletion {
self.example = [[Example alloc] init];
__block BOOL completed = NO;
[self.example exampleWithCompletion:^{
completed = YES;
}];
XCTestExpectation *expectation = [self expectationWithDescription:@"expection needs to be fulfilled"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[expectation fulfill];
});
[self waitForExpectationsWithTimeout:3.0 handler:nil];
XCTAssertEqual(completed, NO);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With