在哪里移动构建一次性依赖项以提高可测试性?

时间:2011-12-30 10:39:46

标签: c# unit-testing design-patterns testability

在我的单元测试中,我使用AssemblyInitializeClassInitializeTestInitialize之类的内容来配置我的测试。在AssemblyInitialize中,我初始化了一些单件工厂来创建服务,一个工作单元和存储库(所有通过Unity / Dependency Injection)。在我的TestInitialize中,我清除状态,他们必须确保每个测试可以独立运行。

Trough Stackoverflow我发现了以下文章:Writing Testable CodeHow to Think About the “new” Operator with Respect to Unit Testing。我不得不说他们改变了我对我写的一些代码的看法,但我的思绪仍在嗡嗡作响。

例如,请使用以下代码:

public class MyPresenter : BasePresenter<IMyView>
{
    public MyPresenter(IMyView view) 
        : base(view)
    {
    }

    public void PrepareView()
    {
        using (IMyService service = ServiceFactory.Instance.CreateService<IMyService>())
        {
            View.Data = service.GetData();
        }
    }
}

在aspx页面中使用的是这样的:

Presenter = new MyPresenter(this);
if (!IsPostback)
{
    presenter.PrepareView();
}

我应该如何改变这种类型与前面的文章?我应该将服务实例传递给PrepareView方法吗?但是我的ASPX页面必须知道服务,工厂和东西,并在使用后处理它。

我的Singleton工厂应该怎么办?使它成为类的属性并通过Unity注入它?

2 个答案:

答案 0 :(得分:3)

我发现这种解析依赖关系不够优秀,看看Ninject连接依赖关系的方式还是注入它们。

你可以看到差异,Service Locator是一个反模式,阅读这个blog也更清楚了.NET中依赖注入的基本目的和实践

答案 1 :(得分:-3)

我只看到两个选项:

  1. 直接注入服务依赖项(但您提到不喜欢在ASPX级别上解析服务)
  2. 传入演示者抽象的DI容器,然后在Presenter中解析依赖关系(但是你提到不喜欢这种方式,因为API不清楚)
  3. 我更喜欢第二个选项,所以每个演示者都知道它需要哪些依赖项,因为你正在使用DI容器(Unity)为什么不摆脱单件工厂并只注册Unity中的所有工厂,这样你就可以访问它了你需要它并且单元测试代码也没有任何麻烦(因为较少的单例)。 因此,只需在每个演示者中传递DI容器(考虑到您注意不要将所有这些保留在ASPX页面中)作为第二个参数,然后解析特定演示者的所有必需服务:

    class Presenter
    {
        public Presenter(IView, IDiContainerAbstraction container)
        ...
    }
    
    Presenter = new MyPresenter(this, unityContainer); 
    public void PrepareView()      
    {  
        using (IMyService service = this.unityContainer.Resolve<IMyService>())
        {
            View.Data = service.GetData();  
        }
    }
    

    所以:

    • 没有单一依赖关系使单元测试成为可能
    • 由于DI容器被界面抽象,因此您可以在演示单元测试时将其传递给单元测试