OCMockito - 带有“willReturn”的模拟类返回nil而不是我指定的值

时间:2013-10-18 07:12:02

标签: objective-c dependency-injection tdd ocmockito

我正在使用的代码看起来像这样: -

- (MyOrange *) getAnOrangeFromBowl:(MyBowl *)bowl withSize:(NSString *)size
{
    MyOrange *orange = [bowl getAnOrangeWithSize:size];
    return orange;
}

在你问之前,我不能直接调用我的“MyBowl”对象的方法,它需要以与这个问题无关的原因这样做。

所以,我想在上面的方法中测试,使用某些参数调用[bowl getAnOrangeWithSize]。我想模拟MyBowl类,因为它不是在这里测试的,只有上面的方法。我还希望[bowl getAnOrangeWithSize]调用返回MyOrange的模拟 - 在这个例子中仅用于比较目的,但可能我也可能在上面的方法中使用那个“橙色”的东西。我也想写那些测试。

为了测试这个,我想注入一个依赖项(MyBowl mock),然后注入另一个模拟依赖项(MyOrange)。我已多次遇到这个要求,并已经重构以解决它,但在这种情况下,我被卡住了。

无论如何,我的测试是: -

- (void)testThatGetAnOrangeFromBowlIsReturningAValidOrange
{
    MyOrange *mockOrange = mock([MyOrange class]);
    MyBowl *mockBowl = mock([MyBowl class]);

    [given([mockBowl getAnOrangeWithSize:@"large"]) willReturn:mockOrange];
    MyOrange *returnedOrange = [sut getAnOrangeFromBowl:mockBowl withSize:@"large"];

    assertThat(returnedOrange, is(equalTo(mockOrange)));
}

测试失败,因为返回的范围是零。在代码中放置一个断点,我可以看到对“getAnOrangeWithSize”的调用返回nil,所以它显然没有注意到我指定的给定/ willReturn指令。

我一直在搜索文档&在这个尝试各种想法但我没有运气的时候挠了一下头。有没有办法让测试工作,或者这是OCMockito不支持的东西(如果是的话,Kiwi可以处理这个问题)吗?提前谢谢。

编辑:似乎可以在新西兰语中做到这一点,如下所示: -

it(@"should return a valid Orange", ^{
    id mockOrange = [MyOrange mock];
    id mockBowl = [MyBowl mock];

    [mockBowl stub:@selector(getAnOrangeWithSize:) andReturn:mockOrange];

    MyOrange *returnedOrange = [sut getAnOrangeFromBowl:mockBowl withSize:@"whatever"];
    [[returnedOrange should] equal:mockOrange];
});

如果在sut的代码中调用了mockOrange中的方法,可以将mockOrange设置为nullMock或创建处理这些调用的存根。

我对新西兰人来说很新,所以上述情况可能并不理想。我还没有发现如何创建一个只与传入的某些参数值一起工作的存根,这样你就可以创建一个(使用上面的例子)一个@“large”的大小返回一个MyOrange实例,并且@ “发霉的”又回来了 - 但我想这是另一个问题的话题,如果我找不到它的完成方式。

我仍然非常想知道上述新西兰代码的OCMockito / Hamcrest等价物,所以我现在将其留作未答复。

1 个答案:

答案 0 :(得分:2)

您的示例在OCMockito中运行正常,因此您的示例代码不是问题。它是其他地方的代码 - 或者,我怀疑,不是存在的代码:

OCMockito将{OCHamcrest匹配器用于given方法参数。如果提供的参数不是匹配器,则将其包装在equalTo(…)匹配器中。

但如果有问题的类没有实现-isEqual:,那么相等匹配器永远不会满足。默认情况下,OCMockito会返回nil以查找没有匹配given语句的内容。

因此,要么是有问题的类需要实现相等,要么在given语句中明确指定不同的匹配器。在这种情况下,我通常使用sameInstance(…)来测试身份而不是相等。有时论证本身并不重要,在这种情况下我使用anything()