首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置Kiwi中模拟方法的参数期望值

如何设置Kiwi中模拟方法的参数期望值
EN

Stack Overflow用户
提问于 2013-03-07 10:59:23
回答 1查看 3.2K关注 0票数 2

使用OCMockito和OCHamcrest,我可以对模拟方法的参数设置期望,如下所示:

代码语言:javascript
复制
[verify(aMockObject) doSomething:allOf(is(instanceOf([NSArray class])), hasCountOf(3U), nil)];

似乎没有一种同样简单的方法可以使用Kiwi来实现这一点。使用间谍捕获争论是可能的,例如:

代码语言:javascript
复制
KWCaptureSpy *spy = [aMockObject captureArgument:@selector(doSomething:) atIndex:0];
NSArray *capturedArray = spy.argument;

然后检查捕获对象的期望值:

代码语言:javascript
复制
[[capturedArray should] haveCountOf:3U];

在新西兰,有没有一种不那么笨拙的方法?

(我知道我可能会在这里使用hamcrest matchers,但目前我正在探索Kiwi的能力)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-28 11:04:22

我使用的一个选项是stub:withBlock:

代码语言:javascript
复制
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];

这工作得很好,而且我发现它比spy模式更容易实现。但是你的问题让我对expectations using message patterns产生了怀疑。例如:

代码语言:javascript
复制
[[[aMockObject should] receive] doSomething:myArray];
[[[aMockObject should] receive] doSomething:any()];

第一个示例将验证aMockObject是否收到了带有参数isEqual:myArraydoSomething:消息。第二个示例将简单地验证是否发送了doSomething:,而不期望数组参数。如果我们可以在消息模式中指定某种类型的匹配器,以表示我们不关心消息中发送的特定数组实例,只要它的count为3,那就太好了。

我还没有找到任何能够做到这一点的例子,但看起来有一些可能性。为了验证消息发送预期,Kiwi使用KWMessagePattern类,特别是matchesInvocation:argumentFiltersMatchInvocationArguments:方法。这将检查三种类型的“参数过滤器”:

使用isEqual:

  • An类型的value

  • Objects对象(如上例中的myArray )与消息中发送的实际值进行比较的
  1. 文字对象值(如上例中的KWAny宏),它将匹配任何满足[KWGenericMatchEvaluator isGenericMatcher:argumentFilter]的参数value
  2. Objects,这基本上意味着该对象响应matches:(id)obj

因此,您应该能够在消息模式预期中使用实现matches:的对象来做一些事情,比如验证发送到存根方法的数组的长度,而无需求助于spy或块。下面是一个非常简单的实现:()

代码语言:javascript
复制
// 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的内置matcher类,那就太好了,但我还没有找到具体的方法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15262264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档