如何将Autofac链接到UnitTesting

本文关键字:UnitTesting 链接 Autofac | 更新日期: 2023-09-27 18:29:04

在我的Web API中,我已经将Autofac链接为IoC容器,我这样做:

域级别

public class Autofac
{
    protected ContainerBuilder Builder { get; set; }
    public Autofac()
    {
        this.Builder = new ContainerBuilder();
    }
    public virtual IContainer Register()
    {
        // Register dependencies
        SetUpRegistration(this.Builder);
        // Build registration.
        var container = this.Builder.Build();
        // End
        return container;
    }   
    private static void SetUpRegistration(ContainerBuilder builder)
    {
        // === DATALAYER === //
        // MyRepository
        builder.RegisterType<MyRepository>()
            .As<IMyRepository>()
            .InstancePerLifetimeScope();
        // === DOMAIN === //
        // MyManager
        builder.RegisterType<MyManager>()
            .As<IMyManager>()
            .InstancePerLifetimeScope();
    }
}

Web API

public class Autofac : Domain.IoC.Autofac
{
    public IContainer Register(HttpConfiguration config)
    {
        // Register your Web API controllers.
        base.Builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        // OPTIONAL: Register the Autofac filter provider.
        base.Builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
        // Complete registration and get container instance.
        var container = base.Register();
        // Set the dependency resolver to be Autofac.
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        // Done.
        return container;
    }
}

正如您所看到的,它继承了来自Domain的基类,并设置了特定于Web API的配置。

用法

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    new IoC.Autofac().Register(GlobalConfiguration.Configuration);
}

正如你所知,这是在global.asax上。

问题

这对Web API很好,但我不知道我需要做什么才能在UnitTest项目上下文中注册所有这些。

这个想法是,我将在Web API级别创建一个与Autofac类类似的实现,但不是使用mock(完全忽略来自Domain的基类)。

有指针吗?

如何将Autofac链接到UnitTesting

就我个人而言,我从未认为有必要(我很难理解它有多可行或有多有用)直接在单元测试中设置我的IoC容器。由于单元测试用于测试一段逻辑代码,该代码可以快速构建、轻松运行,并且不需要太多(我不主张)拆卸。它不应该要求为运行测试设置所有应用程序。

请记住,您的单元测试只是测试通过系统的数据流,即您的DomainManager实际上将在您期望它应该调用的时候调用IRepository。然后,您将为所有存储库提供单独的测试类,以确定它们是否会正确添加到数据库等。

我不确定如何使用DBContext类,但作为包装器的一个示例,这就是它的样子。

interface IDBSetWrapper
{
    object Add(object entity);
}
interface IDBContextWrapper
{
    ...
    IDBSet Set(Type entityType);
    ...
}
class DBContextWrapper : IDBContextWrapper
{
    private readonly DBContext context;
    public DBContextWrapper()
    {
        context = new DBContext();
    }
    ...
    public IDBSet Set(Type entityType)
    {
        var dbSet = context.Set(entityType);
        return new DBSetWrapper(dbSet);
    }
    ...
}

虽然不多,但我希望它能证明我对薄包装的理解。基本上,包装器是DBContext,并将在类中包含它的一个实例,当您请求包装器执行任何操作时,将调用实际的DBContext。我已经展示了当返回另一个对象(在本例中是DBSet)时会发生什么,它也将被包装在一个带有接口的单独对象中。这样您就可以轻松地模拟此类的返回。

现在,您可以将这个新的包装器添加到IoC中,因为它提供了一个接口。

需要注意的一点是,你将无法也可能不希望测试包装类,在我看来,这几乎没有什么意义。但之前我见过同事们对这类类类进行集成测试。