我可以使用Moq集成访问UnitTests中Autofac的全部功能吗 [英] Can I access the full power of Autofac in UnitTests, using the Moq integration

查看:58
本文介绍了我可以使用Moq集成访问UnitTests中Autofac的全部功能吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目(发生在 Orchard 之上的项目,尽管我不认为相关)使用 Autofac . 我正在编写单元测试,我想使用 Moq 消除所有依赖关系,而我正在使用 Autofac/Moq集成即可实现.

这对于作为构造函数参数传递的任何简单依赖项都很好. (Autofac文档在此处)中提供了详细信息.). >

但是因为我从来没有一个containerBuilder,所以我看不到如何使用许多Autofac的功能-解决方案

您提到的某些功能可以与AutoMock类一起使用,而有些功能将不再有意义.使用AutoMock,我们不需要处理ContainerBuilder类,这是简单起见,我们不需要编写所有注册指令,而只注册对我们感兴趣的指令.因此,从使用GetLoose或GetStrict方法创建AutoMock对象开始,我们仅处理已准备好解决问题的已构建IContainer对象.对我们来说幸运的是,IContainer仍然允许我们扩展其注册集,但是Autofac不支持其方便的扩展方法,因为它们被构建为可与ContainerBuilder对象一起使用.这是完全合理的,因为对于Autofac透视图,在IContainer对象上扩展定义是不常见的. ContainerBuilder应该处理注册,而IContainer应该处理解析.

在这里,我将举例说明如何通过AutoMock使用自动连线属性功能:

using (var mock = AutoMock.GetLoose())
{
    mock.Container.ComponentRegistry.Register(
        RegistrationBuilder
            .ForType<MyClass>()
            .PropertiesAutowired()
            .CreateRegistration<MyClass, ConcreteReflectionActivatorData, SingleRegistrationStyle>()
    );
}

正如您现在所看到的,我们必须处理所有通常由扩展方法隐藏的autofac内部代码.属性Autowired功能可以很容易地与AutoMock一起使用,但是lamda注册将不再有意义. lambda注册给我们的是,在ContainerBuilder中注册的对象可以依赖于其他注册的对象,这些对象将在将ContainerBuilder构建为IContainer的过程中解决,因此我们不需要关心注册指令的顺序.在这里,我们已经准备好了IContainer,并且不会再次构建它,因此这种注册延迟毫无意义.如果我们想将某个已经注册的对象传递给某个注册对象,则可以先简单地解决它,然后再使用它.

因此,作为摘要:

  • autofac功能通常可以通过AutoMock访问
  • 由于不能在ContainerBuilder中而不是在IContainer对象中注册,因此某些功能不可用.其他内容可能尚未实现,将来可能会提供.
  • 对于几乎所有情况,都有很好的解决方法,如上面的示例所示

My project (which happens built on top of Orchard, though I don't think that's relevant) uses Autofac. I am writing unit tests in which I want to stub out any dependencies using Moq, and I'm using the Autofac/Moq integration to achieve this.

This is fine for any simple dependencies that are being passed in as constructor arguments. (Autofac documentation provides details of how to achieve this here).

But because I don't ever have a containerBuilder, I don't see how to use a lot of Autofac's power - lamda registration, registering generics, marking properties to be auto-wired. etc.

  • Am I wrong and it is accessible somehow?
  • Is this stuff just not available due to some inherent constraint of the scenario?
  • Is it possible, just not implemented in this Autofac/Moq integration (yet)?
  • Is there a good work around?

解决方案

Some of the features, you've mentioned, can be used with AutoMock class and some won't make sense any more. With AutoMock we do not deal with ContainerBuilder class - this is for simplicity, we don't want to have to code all those registering instructions, but to only register the ones interesting for us. So from creation of AutoMock object with GetLoose or GetStrict method we deal only with built IContainer object ready to resolve things. Fortunately for us IContainer still allows us to extend its registration set, however Autofac won't support that with its convenient extension methods as they are built to work with ContainerBuilder object. This is perfectly reasonable because for Autofac perspective extending definitions on IContainer object is something uncommon. ContainerBuilder is supposed to handle registration and IContainer is supposed to handle resolving.

Here I will, as an example, present how with AutoMock we may use auto-wired properties functionality:

using (var mock = AutoMock.GetLoose())
{
    mock.Container.ComponentRegistry.Register(
        RegistrationBuilder
            .ForType<MyClass>()
            .PropertiesAutowired()
            .CreateRegistration<MyClass, ConcreteReflectionActivatorData, SingleRegistrationStyle>()
    );
}

As you see now we have to deal with all the ugliness of autofac internal code which normally is hidden by extension methods. PropertiesAutowired functionality may be easily used with AutoMock, however lamda registration will not make much sense any more. What lambda registration gives us is that object being registered in ContainerBuilder can depend on other registered object which will be resolved during building ContainerBuilder to IContainer so we do not need to care for the order of the registering instructions. Here we already have ready made IContainer and it won't be built again so such deffering of registration is pointless. If we want to pass to some registered object another already registered object then we may simply resolve it first and then use it.

So as summary:

  • autofac features are generally accessible with AutoMock
  • some of the features are not available due to constraints of not registering things in ContainerBuilder but in IContainer object instead. Other stuff is probably not implemented yet and maybe will be delivered in future.
  • for almost all cases there are good workarounds as shown in the example above

这篇关于我可以使用Moq集成访问UnitTests中Autofac的全部功能吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆