0

I have the following Objective C test code in a SenTestCase class. I get no errors, but the httpReceiveDataFinished method never gets called. Is this because the test is ended before the delegate has a chance to process the http method?

If that is the case how can I spin off a thread (or something similar) to make the test wait for a few seconds?

Thanks a million for any help. I have programmed Java for years, but Objective-C only a few days.

- (void)testExample
{
    HttpClient *client = [[HttpClient alloc] init];
    client.method = METHOD_GET;
    client.followRedirects = YES;
    [client processRequest:@"http://google.com" delegate:self];
    NSLog(@"Test Over");
}

-(void) httpReceiveError:(NSError*)error {
    NSLog(@"***\n%@\n***",[error description]);
}

- (void) httpReceiveDataChunk:(NSData *)data {
    [self.httpResponseData appendData:data];
}

-(void) httpReceiveDataFinished {
    NSString *result = [[NSString alloc] 
        initWithData:self.httpResponseData 
        encoding:NSUTF8StringEncoding];
    NSLog(@"***\nRESULT: %@ \n***",result);
}
john.stein
  • 535
  • 4
  • 8

1 Answers1

0

First: Stanislav's link is excellent. For myself, I needed something that was more flexible (run for long durations) but would also pass the test immediately on success. (Large file downloads and the like.)

Here's my utility function:

-(BOOL)runLooperDooper:(NSTimeInterval)timeoutInSeconds 
      optionalTestName:(NSString *)testName 
{
    NSDate* giveUpDate = [NSDate dateWithTimeIntervalSinceNow:timeoutInSeconds];
    // loop until the operation completes and sets stopRunLoop = TRUE
    // or until the timeout has expired

    while (!stopRunLoop && [giveUpDate timeIntervalSinceNow] > 0) 
    {
        // run the current run loop for 1.0 second(s) to give the operation code a chance to work
        NSDate *stopDate = [NSDate dateWithTimeIntervalSinceNow:1.0];
        [[NSRunLoop currentRunLoop] runUntilDate:stopDate];
    }

    STAssertTrue(stopRunLoop, 
                 @"%@ failed to finish before runloop expired after %f seconds", testName, timeoutInSeconds);
    return stopRunLoop;
}

Declare stopRunLoop as an ivar in your tester-class. Make sure to reset stopRunLoop to FALSE in your setUp function, and call this function prior to calling your [client processRequest:@"http://google.com" delegate:self]; Then, in your event handlers, set stopRunLoop to TRUE.

By passing it a testName, you can reuse it for multiple tests and get some meaningful error messages.

Edit: 99% sure I based the above code off of another StackOverflow post that I can't find at the moment, or I'd link it.

MechEthan
  • 5,703
  • 1
  • 35
  • 30