使用OCMockito和OCHamcrest,我可以设置对模拟方法的参数的期望,因此:
[verify(aMockObject) doSomething:allOf(is(instanceOf([NSArray class])), hasCountOf(3U), nil)];
使用Kiwi似乎没有一种等效的简单方法。可以使用间谍捕获参数,例如:
KWCaptureSpy *spy = [aMockObject captureArgument:@selector(doSomething:) atIndex:0];
NSArray *capturedArray = spy.argument;
然后检查捕获对象的期望:
[[capturedArray should] haveCountOf:3U];
在新西兰这样做是不是一种不那么笨拙的方式了?
(我知道我可能会在这里使用hamcrest匹配器,但目前我正在探索Kiwi的能力)。
答案 0 :(得分:4)
我使用的一个选项是stub:withBlock:
NSArray* capturedArray; // declare this as __block if needed
[aMockObject stub:@selector(doSomething:)
withBlock:^id(NSArray *params) {
capturedArray = params[0];
// this is necessary even if the doSomething method returns void
return nil;
}];
// exercise your object under test, then:
[[capturedArray should] haveCountOf:3U];
这很好用,我发现它比间谍模式更容易实现。但是你的问题让我对expectations using message patterns感到疑惑。例如:
[[[aMockObject should] receive] doSomething:myArray];
[[[aMockObject should] receive] doSomething:any()];
第一个示例将验证aMockObject
是否收到doSomething:
消息,其参数为isEqual:myArray
。第二个示例将简单地验证doSomething:
是否已发送,而不期望阵列的争用。如果我们可以在消息模式中指定某种类型的Matcher,表示我们不关心消息中发送的特定数组实例,只是它的count
为3。
我还没有找到能够做到这一点的任何例子,但看起来有一些可能性。为了验证发送消息的期望,Kiwi使用KWMessagePattern
类,特别是matchesInvocation:
和argumentFiltersMatchInvocationArguments:
方法。这将检查三种类型的“参数过滤器”:
myArray
),与使用isEqual:
的消息中发送的实际值进行比较KWAny
类型的对象(例如上例中的any()
宏),它将匹配任何参数值[KWGenericMatchEvaluator isGenericMatcher:argumentFilter]
的对象,这基本上意味着对象响应matches:(id)obj
因此,您应该能够在消息模式期望中使用实现matches:
的对象来执行诸如验证发送到存根方法的数组长度之类的操作,而无需使用spys或blocks。这是一个非常简单的实现:( available as a Gist )
// A reusable class that satisfies isGenericMatcher:
@interface SOHaveCountOfGenericMatcher : NSObject
- (id)initWithCount:(NSUInteger)count;
- (BOOL)matches:(id)item; // this is what KWMessagePattern looks for
@property (readonly, nonatomic) NSUInteger count;
@end
@implementation SOHaveCountOfGenericMatcher
- (id)initWithCount:(NSUInteger)count
{
if (self = [super init]) {
_count = count;
}
return self;
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(count)])
return NO;
return [item count] == self.count;
}
@end
// Your spec:
it(@"should receive an array with count 3", ^{
NSArray* testArray = @[@"a", @"b", @"c"];
id argWithCount3 = [[SOHaveCountOfGenericMatcher alloc] initWithCount:3];
id aMockObject = [SomeObj nullMock];
[[[aMockObject should] receive] doSomething:argWithCount3];
[aMockObject doSomething:testArray];
});
能够在这里重用Kiwi的内置匹配器类会很好,但我还没有找到确切的方法。