使用依赖注入来测试UIViewController

大家好,当我们开始编码以创建需要其他对象才能工作的对象时,这是很常见的,例如在Car类中,需要Person对象来启动引擎和驱动器( starEnginedrive是需要Person实例的假设方法)。 所以我们可以说Car需要一个Person来工作。

上面的代码向我们展示了Jhon正在驾驶我们的汽车,只有Jhon可以做到! 因为每个Car对象都会创建一个名为Jhon的Person的实例。 但是,如果玛丽想开车怎么办? 我们如何重写该代码以让Mary开车?

我们可以将一个Person传递到我们的Car ,使其可用于Person任何实例,换句话说:可重用。 我们不在乎如何创建Person对象,如果它是由工厂,另一个类创建的,或者它需要名称,年龄或任何其他依赖关系,我们只需要一个Person实例即可。

在软件工程中, 依赖项注入是一种技术,通过该技术,一个对象(或静态方法)可以提供另一个对象的依赖项。 依赖项是可以使用的对象(服务)。 注入是将依赖项传递给将使用它的依赖对象(客户端)。

让我们把这个例子转为日常问题。 在下面的代码中,我们的ViewController使用ListService对象。 这个ListService从Web服务加载数据,但是如果我们想从本地数据库,文件或其他地方加载数据怎么办? 我们需要创建另一个ViewController吗? 如果我们要测试此ViewController如何使API响应始终保持相同,以便可以验证测试?

现在考虑对此类进行测试,每次运行测试时,我们至少需要Internet连接和稳定的响应。 这使我们的测试变慢且不可行。 解决方案中使用依赖项注入来使用自定义的模拟ListService对象。

一种实现方法是创建一个具有load方法的接口,并在自定义对象中实现它。 换句话说,我们创建了Service协议和对象,它们知道如何从Web服务器,数据库,文件等中加载数据。

通过这种方法,我们可以轻松创建要使用的各种Service 。 例如,一个服务从Web服务加载数据,第二个服务从本地数据库加载数据,最后一个服务被模拟,因此我们可以使用它来测试ViewController而无需真正的API响应或本地数据库中的数据。

每种Service对象都可以具有唯一的依赖关系。 我们的WebServiceListService将需要知道如何发出请求,因此将需要一个Request对象。 DataBaseListService需要数据库连接才能加载数据。 这些独特的依赖关系对于我们的ViewController是不可见的。 它只需要一个具有load()方法的Service对象。

要测试我们的ViewController我们只需要创建一个MockListService并在测试期间将其注入即可。

注入对象使我们的代码解耦并且更易于测试。 这可以通过构造函数,setter或接口传递对象来实现。

附:如果您喜欢这篇文章,请在Twitter上分享,或在中级推荐,或两者都=)。 这确实有助于我吸引更多人。 非常感谢。