【问题标题】:When making unit tests for objective C, how do you test blocks?在为目标 C 进行单元测试时,如何测试块?
【发布时间】:2011-04-13 02:53:29
【问题描述】:

我有一个函数(内部使用 ASIHTTPRequest)调用一个带有结果的块:

[Http get:@"http://api.geonames.org/postalCodeLookupJSON"
   params:params cacheMins:0 complete:^(NSDictionary *response, BOOL success) {
       STAssertTrue(success, @"JSON retrieved OK");
       STFail(@"blah");
}];

我想测试上述内容,但似乎没有调用测试。

如何确保测试等到调用块?

-编辑-

当然我不建议在 gui 线程的主应用程序中执行此操作,在这种特殊情况下,它仅用于单元测试。

【问题讨论】:

    标签: objective-c unit-testing lambda objective-c-blocks


    【解决方案1】:

    找到解决办法:

    Wait for code to finish execution

    例如:

    __block int done=0;
    [Http get:@"http://api.geonames.org/postalCodeLookupJSON"
       params:params cacheMins:0 complete:^(NSDictionary *response, BOOL success) {
           STAssertTrue(success, @"JSON retrieved OK");
           NSArray *postalcodes = [response objectForKey:@"postalcodes"];
           NSDictionary *first = [postalcodes objectAtIndex:0];
           NSString *adminName1 = [first objectForKey:@"adminName1"];
           STAssertTrue([adminName1 isEqualToString:@"New South Wales"], @"NSW");
           done=1;
    }];
    
    // https://stackoverflow.com/questions/3615939/wait-for-code-to-finish-execution
    while (!done) {
        // This executes another run loop.
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        // Sleep 1/100th sec
        usleep(10000);
    }
    

    【讨论】:

    • sleep(10) 不会停止当前线程(不是运行块的线程)吗?如果它是您的主线程,则您从中启动块,那么睡眠将阻塞 GUI。
    • 糟糕,我将对其进行编辑。应该是“睡眠”。你是对的,它会停止主线程并停止 gui。但是 - 这只是用于单元测试。
    【解决方案2】:

    不确定我在哪里找到的,但有一种更好的方法,不使用睡眠:

    while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !placeMarkUpdated){};
    

    在上下文中,测试反向地理编码请求:

    __block BOOL placeMarkUpdated = NO;
    
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        if (placeMarkUpdated == NO) {
            placeMarkUpdated = YES;
            CLPlacemark *placemark = [placemarks objectAtIndex:0];
            address = [Address addressFromPlacemark:placemark];
        }
    }];
    
    while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !placeMarkUpdated){};
    

    睡眠很糟糕,因为它们会减慢构建速度(我知道 5s 听起来不错,但考虑一下老故事:一个人去看医生,因为他的膝盖因跑步而受伤,医生说“站起来”并轻拍他的膝盖说“疼吗?”男人说“不”,医生:“如果我做了 10K 次就会……”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多