为什么使用DI进行模拟比在objective-c中模拟对象更好?

mic*_*rus 7 unit-testing dependency-injection mocking objective-c ios

这篇博客文章说:

虽然有时候有一些明智的方法可以在没有DI的情况下模拟对象(通常是通过模拟类方法,如上面的OCMock示例所示),但它通常是不可能的.即使有可能,测试设置的复杂性也可能超过其好处.如果你一直使用依赖注入,你会发现使用存根编写测试并且模拟会更容易.

但它没有解释原因.id在简单的OCMockito 中,DI(注入符合协议的对象)在Objective-C中更适合模拟的可能场景是什么?

[given([mockArray objectAtIndex:0]) willReturn:@"first"];
 [verifyCount(mockArray, times(1)) objectAtIndex:];
Run Code Online (Sandbox Code Playgroud)

Ada*_*rek 1

我注意到,当原始类执行一些异步操作时,为测试目标创建单独的类会更容易。

假设您为 UIViewController 编写了一个测试,该测试具有 LoginSystem 依赖项,该依赖项使用 AFNetworking 向 API 发出请求。LoginSystem 采用块参数作为回调。(UIViewController->登录系统->AFNetworking)。

如果您模拟 LoginSystem,您可能会遇到如何触发回调块来测试 UIViewController 在成功/失败时的行为的问题。当我尝试使用MKTArgumentCaptor来检索块参数时,我必须在测试文件中调用它。

另一方面,如果您为 LoginSystem 创建一个单独的类(我们称其为 LoginSystemStub,它是从 LoginSystem 扩展的),您就可以在测试文件之外用 3 行代码“模拟”行为。我们还应该保持测试文件干净且可读。

另一种情况是 verify() 不适用于检查异步行为。调用expect(smth2)要容易得多。.equal(smth)

编辑:

指向 NSError (NSError**) 的指针也不能很好地与 verify() 配合使用,最好创建一个存根 :D