所以,我正在读的谷歌测试的博客,和它说,全球状态是坏和使得它很难编写测试。我相信--我的代码是难以测试的权利。所以我如何避免全球状态?

最大的事我用的全球国家(作为我的理解)对管理关键信息之间我们的发展、接受书、以及生产环境。例如,我有一个静态的类命名为"全局"的静态部件称为"DBConnectionString." 当的应用程序负荷,确定哪一连串负荷,并填充Globals.DBConnectionString.我加载的文件路径、服务器名称和其他信息Globals类。

我的一些功能的依赖全球变量。所以,当我测试我的功能,我必须记住以设定某些globals第一或其他测试都将失败。我想避免这种情况。

是否有一个好的方法来管理国家信息?(或者是我的了解全球状态不正确?)

有帮助吗?

解决方案

依赖注射的是什么你要找的。而不是具有这些职能走出去,看看他们的依赖性、注入的依赖关系进入功能。也就是说,当你打电话的功能,通过数据他们想要的给他们。这种方式很容易把一个测试框架的一类,因为可以简单地注入模拟对象在适当情况下。

很难避免一些全球状态,但是这样做的最佳方法是使用工厂的类在最高级别的应用程序,和下面的一切,非常顶级是基于依赖注射。

两个主要好处:一、测试是一个见鬼的很容易,两个,你的应用程序更加松散耦合。你依靠的是能够节目对界面的一类,而不是它的实施。

其他提示

记住如果你的测试涉及实际的资源,例如数据库或文件系统然后你在做什么都是 一体化试验 而不是 单元测试.一体化的测试需要一些初步的设置而有单元的测试应当能够独立运行的。

你可以看到用一个依赖注射框架,例如温莎城堡但是简单的情况下,你可能能够采取一个中间道路的做法,如:

public interface ISettingsProvider
{
    string ConnectionString { get; }
}

public class TestSettings : ISettingsProvider
{        
    public string ConnectionString { get { return "testdatabase"; } };
}

public class DataStuff
{
    private ISettingsProvider settings;

    public DataStuff(ISettingsProvider settings)
    {
        this.settings = settings;
    }

    public void DoSomething()
    {
        // use settings.ConnectionString
    }
}

在现实中你会最有可能从阅读的配置文件在您的执行情况。如果你为,一个完全成熟的DI框架交换的配置的路要走,但我认为这至少是更好的比使用Globals."连接字符串".

伟大的第一个问题。

短的回答:确保应用程序的功能,从其所有的输入(包括隐含的),其产出。

问题你所描述的似乎并不喜欢全球状态。至少不变的状态。相反,什么你描述似乎喜欢什么,往往称为"配置问题",它有一些解决方案。如果你使用爪哇,你可能想看看轻注射框架喜欢 题之一,因.在卡拉,这通常是解决了 隐式转换.在一些语言中,你将能够装载另一个程序配置程序在运行时间。这是我们如何使用配置服务器编写一般和我使用一窗口管理写在Haskell称为Xmonad其配置文件只是一个Haskell的程序。

例的依赖注射在电视设置,这里所说的:

index.php

$container = new Container();
include_file('container.php');

container.php

container.add("database.driver", "mysql");
container.add("database.name","app");

...

$container.add(new Database($container->get('database.driver', "database.name")), 'database');
$container.add(new Dao($container->get('database')), 'dao');
$container.add(new Service($container->get('dao')));
$container.add(new Controller($container->get('service')), 'controller');

$container.add(new FrontController(),'frontController');

index.php 继续在这里:

$frontController = $container->get('frontController');
$controllerClass = $frontController->getController($_SERVER['request_uri']);
$controllerAction = $frontController->getAction($_SERVER['request_uri']);
$controller = $container->get('controller');
$controller->$action();

和你有它,控制器上取决于服务层的对象,这取决于 一个道(数据访问的目的)的对象,这取决于一个数据库对象与取决于 数据库驱动,等名称

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top