2015-04-17 78 views
7

blog article说:为什么用嘲笑DI比嘲笑objective-c中的对象更好?

虽然存在有时明智的方式来模拟出的对象,而不DI (通常通过嘲笑出类方法,如在上面的OCMock例子 看到),它往往平出不可能。即使有可能,测试设置的复杂性可能会超过其好处。如果 您一直在使用依赖注入,那么您会发现编写 使用存根和模拟测试会更容易。

但它不能解释为什么。什么是可能的情况,其中DI(注入id对象符合协议)将用于对在Objective-C嘲笑更好,比简单OCMockito:

[given([mockArray objectAtIndex:0]) willReturn:@"first"]; 
[verifyCount(mockArray, times(1)) objectAtIndex:]; 

回答

1

我注意到,当原始类做一些异步的东西时,为测试目标创建一个单独的类更容易。

假设您为UIViewController编写了测试,该测试具有使用AFNetworking向API请求的LoginSystem依赖关系。 LoginSystem以块参数作为回调。 (UIViewController-> LoginSystem-> AFNetworking)。

如果您对LoginSystem进行了模拟,您可能会遇到问题,如何在成功/失败时触发回调模块来测试您的UIViewController行为。当我试图以MKTArgumentCaptor结尾来检索块参数时,我不得不在测试文件中调用它。另一方面,如果您为LoginSystem创建了一个单独的类(让我们称之为从LoginSystem扩展的LoginSystemStub),那么您可以在3行代码中和测试文件之外“模拟”行为。我们也应该保持我们的测试文件干净可读。

另一种情况是,verify()无法检查异步行为。 (smth2)更容易打电话给 .equal(水木清华)

编辑:

指针到NSError(NSError **)也起不到很好的与验证(),它是更好地创建一个存根:d

+0

谢谢:)所以我认为它符合我的状态“只有当你需要一些超级定制行为才更好。” –

0

想象一下,您正试图测试与其子对象之一交互的对象的更复杂的行为。为了确保父对象正常运行,您必须模拟子对象的所有方法,甚至可能跟踪其变化的状态。

但是,如果你这样做,你只是写了一个全新的对象,混乱和复杂的方式。编写一个全新的对象并告诉父母使用它会更简单。

+0

是你暗示在所有引入混乱的情况下对每一个依赖使用DI,然后创建一个单独的模拟类,比OCMockito存根更清晰/不那么复杂?我不这么认为。 –

+0

在大多数情况下,跟踪模拟的变化状态似乎毫无意义。你需要从模拟中唯一需要的是返回一些数据并找出是否调用了某些方法。 –

0

使用DI,您可以在运行时注入模型,但不会在您的类中绑定,而只会在配置中绑定。
当你想嘲笑你只是创建一个模拟模型,并注入,而不是你的真实数据。除了模型之外,您还可以在一行中更改您的实现。

请参阅here了解其背后的想法或here。免责声明:当然,你可以嘲笑模型以外的其他东西,但这可能是最常见的用例。

+0

是的,我知道如何使用注入模拟类来模拟。我只是想知道,如果使用真正的课程在博客中说得那么优秀,如果是这样,为什么? –

0

答案是:这不是更好。只有你需要一些超级定制行为才更好。

最好的一点是,您不必为每个注入的类创建一个接口/协议,并且您可以将DI注入到真正需要注入的模块中,从而使您的代码变得更加清晰和更多YAGNI。

它适用于任何动态语言或带反射的语言。为了单元测试而创造如此多的混乱让我觉得不好。