3

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

通过 Stackoverflow,我找到了以下文章:编写可测试代码如何考虑单元测试方面的“新”运算符。我不得不说他们改变了我对我编写的一些代码的看法,但我的头脑仍然嗡嗡作响。

例如,采用以下代码:

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 注入它?

4

2 回答 2

3

我发现这种解决依赖关系的方法很不优雅,看看 Ninject 连接依赖关系或注入它们的方式。

可以看出区别,Service Locator 是一种反模式,阅读这篇博客也更清楚了.NET 中依赖注入的本质目的和实践

于 2011-12-30T10:51:39.687 回答
-3

我只看到两个选项:

  1. 直接注入服务依赖项(但您提到不喜欢在 ASPX 级别解析服务)
  2. 传入 Presenter 抽象的 DI 容器,然后在 Presenter 中解析依赖项(但你提到不喜欢这种方式,因为 API 不清楚)

我更喜欢第二个选项,这样每个演示者都知道它需要哪些依赖项,因为您使用的是 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 容器,因此您可以在单元测试时传入演示者 Mock
于 2011-12-30T10:47:41.480 回答