OhadM
OhadM

Reputation: 4803

Monitoring Reachability with AFNetworking in unit test fails

In a project I am working I have implemented the HTTP Manager Reachability example.

When I run the actual app, it goes inside the block and from there to the switch:

[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status) {

In addition, when I call ...reachabilityManager] isReachable method returns true as expected.

The problem occurs when I try to unit test a class method I wrote that uses ...reachabilityManager] isReachable as a precondition - it returns false and what is weird that during a debug I have noticed that it doesn't go inside the above block, it skips it.

Of course, in the actual app it goes inside the block.

I have even tried to mock the class that implements the HTTP Manager Reachability example using OCMock in the unit test but it gave me the same result:

// NetworkClass implements the example
NetworkClass *networkClass = [[NetworkClass alloc] init];
id mockedNetworkClass = OCMPartialMock(networkClass);
// startNetworkMonitoring method implements the whole example above
[mockedNetworkClass startNetworkMonitoring];
// Giving enough time for AFNetworking to finish
[NSThread sleepForTimeInterval:60.0f];

EDIT1:

Looks like semaphore/XCTestExpectation won't help, the problem is in AFNetworkReachabilityManager::startMonitoring:

But it runs outside the unit test even if we use semaphore/XCTestExpectation as mentioned.

Still looking for soultions..

EDIT2:

I was trying to follow the objc.io for Testing Asynchronous Code but it seems to be missing some code and some of the explanations are lacking of integration details.

Upvotes: 1

Views: 530

Answers (1)

Steve Wilford
Steve Wilford

Reputation: 9002

I'd imagine that sleeping the thread is causing issues.

Try using the expectations API documented in Writing Tests of Asynchronous Operations.

Something along the lines of this should get you started (note this is more of a demonstration of the expectations API rather than a complete working test case):

- (void)testReachability {
    XCTestExpectation *expectation = [self expectationWithDescription:@"Wait for reachability"];

    [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        ...

        [expectation fulfill];

    }];

    [self waitForExpectationsWithTimeout:10 handler:^(NSError * _Nullable error) {
        // timed out waiting for reachability
    }];
}

Upvotes: 1

Related Questions