ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 如何将Autofac链接到UnitTesting

2019-07-06 12:09:20  阅读:150  来源: 互联网

标签:c dependency-injection unit-testing inversion-of-control autofac


在我的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类创建一个类似的实现,但是与mocks(完全忽略Domain的基类)相比.

有什么指针吗?

解决方法:

就个人而言,我从来没有看到在单元测试中直接设置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中,因为它提供了一个接口.

有一点需要注意的是,你将无法并且可能不希望测试包装类,因为我看到它的意义非常小.但是之前我见过同事们对这类课程进行了集成测试.

标签:c,dependency-injection,unit-testing,inversion-of-control,autofac
来源: https://codeday.me/bug/20190706/1397187.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有