1

I've been trying to automate tests on asynchronous requests but I haven't been able to run anything in a different thread while the test function was waiting. Here is the test function:

- (void) testBoxManagerConnexionStatus
{
    ControlSender* cs = [ControlSender get];
    requestShouldSucceed = YES;
    [cs startCheckingReachabilityWithDelegate:self];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:TIMEOUT_INTERVAL+1.0]];

    STAssertTrue(downloadComplete, @"Download should be over by now");
}

My test class implements the callback methods this way:

- (void)controlSender:(ControlSender *)controlSender sentSuccessfullyCode:(FreeboxControl)code
{
    if (requestShouldFail) {
        STAssertTrue(NO, @"Request should have failed");
    }
    downloadComplete = YES;

}
- (void)controlSender:(ControlSender *)controlSender couldntSendCode:(FreeboxControl)code details:(NSHTTPURLResponse*)details
{
    if (requestShouldSucceed) {
        STAssertTrue(NO, @"Request should have succeded");
    }
    downloadComplete = YES;
}

But whenever my usual code try to run something in a different thread nothing happens. For example the NSURLConnection never call its delegate methods when allocated:

m_connexion = [[NSURLConnection alloc] initWithRequest:m_networkRequest delegate:self];

Neither the -connectionDidFinishLoading: nor the -connection:didFailWithError:

Same thing for calls like this one:

[self performSelectorInBackground:@selector(BG_startCheckingReachabilityWithDelegate:) withObject:delegate];

Nothings gets called in background when running the test. The same code works fine outside of the test though. Is there any way to test asynchronous url request with OCUnit?

Thanks for the help.

Chris Hanson
  • 54,380
  • 8
  • 73
  • 102
mbritto
  • 898
  • 12
  • 25

2 Answers2

2

you could look at https://github.com/danielpunkass/RSTestingKit which has a way to wait on the run loop in unit tests you can see his slides at http://www.red-sweater.com/talks/UnitTesting.pdf for some background. It may have some info to help you get started.

Sam D
  • 430
  • 4
  • 6
1

You can try running requests like this in a background thread, but you don't want to. For your sanity, you don't want your tests dependent on external services. What if the remote service is down? Your test fails. What if the remote service returns an error? Your test fails? What if you want to what your code does when the remote service responds with an error to a valid request? You can't (consistently). Even if your tests pass they'll run slowly, depending on how long the remote service takes to respond.

Your life will be easier if you stub out the dependency on any remote services for the purpose of your tests. See this answer (and the associated question) for more detailed reasoning.

Community
  • 1
  • 1
Adam Milligan
  • 2,826
  • 19
  • 17
  • Thanks Adam, I already read your previous post when looking up for solutions. The reason why I'm still trying to test those asynchronous call is because they are not with remote service but with a local network (wifi) set top box. – mbritto Dec 01 '10 at 08:36
  • (comment suite, seems that return key validate the comment) The app is a remote control for this set top box and I'd like to make sure the manufacturer does not change the api (url, parameters, etc).Plus, this would help me debug an annoying wifi lost issue when getting out of sleep on the iphone. – mbritto Dec 01 '10 at 08:46
  • I disagree Adam. It sounds like you're coming from one use-case and applying this too broadly. Test cases which rely on remote services are entirely valid, and the only way to properly test end-to-end integration. You ask 'what if the remote service returns and error' - well that's a valid test result! I see what you're getting at with 'stub out dependency'. In some areas of the code, sure. Depends which 'Unit' you're testing. – Chris Hatton Jan 26 '13 at 12:56