2

在我正在测试的代码中,我有一个 NSPredicate 并且我正在过滤一个数组:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"status == %d || status == %d", FVFileReadyStatus, FVFileWaitingStatus];
[myArray filterUsingPredicate:predicate];

我有一个方法来返回一个模拟,最终将被添加到myArray. FVFileStatus是一个 typedef 枚举。因为我使用的是谓词,所以谓词是 call valueForKey,所以我需要把它存根:

-(id)mockFVFileHandleWithStatus:(FVFileStatus)status {
    id mock = [OCMockObject mockForClass:[FVFileHandle class]];
    [[[mock stub] andReturnValue:OCMOCK_VALUE(status)] valueForKey:[OCMArg checkWithSelector:@selector(isEqualToString:) onObject:@"status"]];
    return mock;
}

当我运行我的测试时,它在过滤器上失败了。我得到一个NSInvalidArgumentException - Reason: Return value does not match method signature.

我不确定如何设置存根,以便它可以与 NSPredicate 一起使用。

有人可以帮忙吗?

4

1 回答 1

4

很接近。设置存根的正确方法如下:

[[[mock stub] andReturn:OCMOCK_VALUE(status)] valueForKey:[OCMArg checkWithSelector:@selector(isEqualToString:) onObject:@"status"]];

起初这似乎违反直觉,因为您尝试存根的属性是int类型,因此您希望必须使用andReturnValue:

但是,在模拟对象上调用的实际方法不是status而是valueForKey:,后者的返回类型是id。因此,当使用andReturnValue:时,存根被设置为返回原始值,然后在被要求提供对象时报错。顺便说一句,错误消息可能更清楚,我会调查一下。

您仍然可以使用OCMOCK_VALUE宏来设置值对象,但是通过使用andReturn:您告诉存根返回该值对象,而不是包装在其中的原语,这与valueForKey: ' s 返回类型。

于 2012-06-08T11:11:15.947 回答