2

我正在使用的代码如下所示:-

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

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

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

为了测试这一点,我想注入一个依赖项(MyBowl 模拟),该依赖项又注入另一个模拟依赖项(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)));
}

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

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

编辑:似乎可以在 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 或为处理这些调用而创建的存根。

我对 Kiwi 很陌生,所以上述内容可能不是最佳的。我还没有找到如何创建一个只适用于传入的某些参数值的存根,以便您可以为(使用上面的示例)大小为 @"large" 返回一个 MyOrange 实例和 @ “发霉”返回另一个 - 但如果我找不到它是如何完成的,我想这是另一个问题的主题。

我仍然非常想知道上述 Kiwi 代码的 OCMockito/Hamcrest 等价物,所以我暂时将其保留为未回答。

4

1 回答 1

2

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

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

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

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

于 2013-10-19T17:25:04.870 回答