如何在ASP.NET中使用IoC容器配置单元测试

本文关键字:IoC 配置 单元测试 ASP NET | 更新日期: 2023-09-27 18:09:58

我已经在ASP中配置了Unity。在Application_BeginRequest中接收到第一个请求时加载配置。然后Unity容器存储在全局中。Ascx作为属性,以便我的其他类可以访问它:

public static IUnityContainer ContainerHolder { get; set; }
IUnityContainer IContainerAccessor.Container
{
    get { return ContainerHolder; }
}

ContainerHolder,跨应用程序保存容器实例,容器属性允许在每个会话中访问该属性。

然后我有一个UnityLocator类,使我能够在整个应用程序中访问这个属性:

public static class UnityLocator
    {        
        private static IUnityContainer Container
        {
            get
            {
                return ((IContainerAccessor)HttpContext.Current.ApplicationInstance).Container;
            }
        }
    }

一切正常!

我也有一个从Unity访问实例的方法:

UnityLocator.GetInstance<IThemeManager>();
    protected Repository(ICustomCacheManager customCacheManager)
    {
        this.Cache = customCacheManager;
    }
    protected Repository()
        : this(UnityLocator.GetInstance<ICustomCacheManager>())
    {
    }

这个已经在我的应用中使用了,这样我就可以从Unity中检索一个现有的实例,这样我就可以将它注入到其他类中。例如,我的视图(asp.net页面)将这个作为依赖项注入到它的Presenter类。

现在,我想配置我的单元测试运行。

我怎么能那样做?!全球。ascx显然不存在,所以我认为我应该创建一个BaseTest类,让我所有的测试继承它。然后在这个BaseTest类的构造函数处构建实例。这是正确的做法吗?

如何使用Unity配置单元测试?

感谢

更新:UnityLocator。GetInstance补充道。

如何在ASP.NET中使用IoC容器配置单元测试

您不应该担心访问您的IoC容器。这违反了单元测试。

在单元测试中,你不应该担心任何具体的实现或依赖(除了被测试的类)。

对我来说,让你的IoC全局可用是一个糟糕的设计选择。你应该通过属性或构造函数注入你的依赖项。

使用全局应用程序类来存储服务定位器可能不是一个好主意。为什么不使用内置的ServiceLocator类呢?它可以在代码中的任何地方使用,并且不依赖于全局应用程序/HttpContext。

是否在单元测试中使用容器是另一回事。我个人并不反对这样做,只要你把服务的存根实现放到容器中。

编辑:使用ServiceLocator配置容器的方法:

    private void ConfigureUnity()
    {
        UnityServiceLocator locator = new UnityServiceLocator( ConfigureUnityContainer() );
        ServiceLocator.SetLocatorProvider( () => locator );
    }
    private IUnityContainer ConfigureUnityContainer()
    {
        IUnityContainer container = new UnityContainer();
        // this loads container's configuration, comment or uncomment
        container.LoadConfiguration();
        return container;
    }

然后可以从定位符内部访问容器,如:

var container = ServiceLocator.Current.GetInstance<IUnityContainer>();

在您的页面中,尝试这样做:

public class DepartmentReportPage : Page
{
    private readonly DepartmentReportPresenter _presenter;
    public DepartmentReportPage()
    {
        this._presenter =
            UnityLocator.GetInstance<DepartmentReportPresenter>();
        this._presenter.View = this;
    }
}