objective-c - OCMock 测试传递 block 是否正确执行

标签 objective-c unit-testing ocmock

我如何验证传递的 block 是否正确执行?

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    [self updatePostalCode:newLocation withHandler:^(NSArray *placemarks, NSError *error) {
    // code that want to test
        CLPlacemark *placemark = [placemarks objectAtIndex:0];
        self.postalCode = [placemark postalCode];
        _geocodePending = NO;
    }];

    ....
}

我想知道 postalCode、_geocodePending 设置是否正确,但我无法弄清楚如何使用 OCMock 执行此操作。

添加代码

id mockSelf = [OCMockObject partialMockForObject:_location];

    id mockPlacemart = (id)[OCMockObject mockForClass:[CLPlacemark class]];

    [[[mockPlacemart stub] andReturn:@"10170"] postalCode];

    [mockSelf setGeocodePending:YES];
    [mockSelf setPostalCode:@"00000"];

    [self.location handleLocationUpdate]([NSArray arrayWithObject:mockPlacemart], nil);

    STAssertFalse([mockSelf geocodePending], @"geocodePending should be FALSE");
    STAssertTrue([[mockSelf postalCode] isEqualToString:@"10170"], @"10170", @"postal is expected to be 10170 but was %@" , [mockSelf postalCode]);

最佳答案

从类中的方法返回处理程序 block 。 There are a few good reasons to do this ,包括可测试性。

- (void (^)(NSArray *, NSError *))handleLocationUpdate {
    __weak Foo *weakself = self;
    return ^(NSArray *placemarks, NSError *error) {
        CLPlacemark *placemark = [placemarks objectAtIndex:0];
        weakself.postalCode = [placemark postalCode];
        weakself.geocodePending = NO;
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    [self updatePostalCode:newLocation withHandler:[self handleLocationUpdate]];

    ....
}

然后,在你的测试中:

-(void)testLocationUpdates {
    id mockPlacemark = [OCMockObject mockForClass:[CLPlacemark class]];
    [[[mockPlacemark stub] andReturn:@"99999"] postalCode];

    myClass.geocodePending = YES;
    myClass.postalCode = @"00000";

    [myClass handleLocationUpdate]([NSArray arrayWithObject:mockPlacemark], nil);

    expect(myClass.geocodePending).toBeFalsy;
    expect(myClass.postalCode).toEqual(@"99999");
}

关于objective-c - OCMock 测试传递 block 是否正确执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11189587/

相关文章:

iphone - MPMediaItem 如何播放?

php - 通过 MySQL 数据库发送 iOS 表情符号

ios - 加载 XCTest 时出错,找不到合适的图像。

ruby - 依赖于本质上随机的实例变量的测试方法

iphone - 带有参数的方法上的 OCMock 并返回一个值

iphone - 保存查询值

Ruby:Minitest、测试单元和实例变量

ios - 无法使用 OCMock stub [CLLocationManager AuthorizationStatus]

objective-c - 在 Objective-C 中模拟指向指针的指针

ios - iOS7 上的 NSFileManager 无限循环