具有在线功能的单元测试课程


23

当类的单元测试功能具有需要在线功能的私有功能时。人们将如何进行测试?

例如:

public class Foo
{
    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        CloudService c = new CloudService();
        int oval = c.getValueFromService();
        return oval;
    }
}

如果我要测试功能:“ methodA()”,它将尝试使用“ goOnlineToGetVal()”,但是如果此测试在没有功能的情况下,它将尝试联机。不上网怎么办100%的课堂覆盖率?


您的方法只是调用云API,还是做其他工作?
Winston Ewert 2014年


4
依赖注入
PhaDaPhunk

Answers:


76

new CloudService()

还有你的问题。

现代的OO设计建议传递这种依赖关系而不是直接构造这种依赖关系。这可以传递给函数本身,也可以在构造时传递给类。如果需要保证这种复杂性,也可以通过“控制反转”容器来捕获或聚合它。

那时,传递模拟/伪造服务以在测试过程中为您提供“在线”数据变得相当琐碎。更好的是,它使您的软件具有足够的灵活性,以便您可以在某些(政府?)客户端出现但又不想使用云来实现其价值时迅速进行调整。或者您想将一个云服务提供商转给另一个云服务提供商。要么...


7
我想我进一步了解了什么是依赖依赖注入。
marczellm 2014年

创建应用程序所需的所有实例的最佳位置在哪里?尽可能靠近我的应用程序的顶部?到目前为止,您只能应用依赖项注入。在某些时候,您需要自己创建实例,而不是将它们作为参数传递。
保罗

3
@Paul-视情况而定。以我的经验,应用程序通常看起来像二叉树-一个类/函数/模块将两个粘合在一起以提供一些更复杂的行为。这些“胶水”类之一是指定具体实现的类,依次由上方的东西使用它将其与其他东西胶合,然后……直到最终到达将大块胶合在一起的入口点连贯地 “最佳”位置是使您的代码可以执行其需要做的事情,而不必执行或不应该执行的操作的地方。会有所不同。
Telastyn 2014年

2
@Paul通常,您的应用程序分为直接测试并应使用这种依赖注入的“库”和特定于应用程序的代码。后者通常可以归结为某些GUI,某些Web服务或某些命令行界面,这些界面可以直接使用用户提供的数据来调用该库。本质上,特定于应用程序的代码将创建依赖项注入库期望的具体实现。
Darkhogg 2014年

@Paul看一下IoC容器,例如温莎城堡,StructureMap,Ninject和Unity。他们绝不做依赖注入的唯一方法,但是它们可以在关于构建对象图,从上而下的思维而言是非常丰富
本·阿伦森

37

我会这样实现:

public class Foo
{
    private ICloudService cloudService;

    public Foo(ICloudService s)
    {
       cloudService=s;
    }

    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        int oval = cloudService.getValueFromService();
        return oval;
    }
}

该接口ICloudService既可以通过用于测试的模拟来实现,也可以通过“真实”云服务来实现。当实例化new CloudService()对于的每次调用都是强制性的getValueFromService,或者CloudService是来自无法更改的第三方API时,请实现包装器,派生自ICloudService并进行适当的调用。


1
这绝对是要走的路。有一些类库可以模拟一个接口,使您可以完全控制测试。
格雷格·伯格哈特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.