我可以使用Moq集成在UnitTests中访问Autofac的全部功能吗?

时间:2015-02-23 19:43:50

标签: c# unit-testing mocking moq autofac

我的项目(建立在Orchard之上,虽然我没有认为相关的)使用Autofac。 我正在编写单元测试,我希望使用Moq来删除所有依赖项,并且我使用Autofac/Moq integration来实现此目的。

这适用于作为构造函数参数传递的任何简单依赖项。 (Autofac文档提供了如何实现此here)的详细信息。

但是因为我没有容器,所以我不知道如何使用很多Autofac的强大功能 - lamda registrationregistering generics,将属性标记为auto-wired。等

  • 我错了,以某种方式可以访问?
  • 由于场景的一些固有约束,这些东西是不可用的吗?
  • 是否有可能,但尚未在此Autofac / Moq集成中实现?
  • 有好的工作吗?

1 个答案:

答案 0 :(得分:2)

您提到的一些功能可以与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内部代码的所有丑陋。 PropertiesAutowired功能可以很容易地与AutoMock一起使用,但lamda注册将不再有意义。 lambda注册给我们的是在ContainerBuilder中注册的对象可以依赖于在将ContainerBuilder构建到IContainer期间解析的其他注册对象,因此我们不需要关心注册指令的顺序。在这里,我们已经准备好了IContainer并且它不会再次构建,因此这种注册的失败是毫无意义的。如果我们想要将另一个已注册的对象传递给某个已注册的对象,那么我们可以先解决它然后再使用它。

总结如下:

  • autofac功能通常可通过AutoMock访问
  • 由于没有在ContainerBuilder中注册事物但在IContainer对象中注册的限制,某些功能不可用。其他的东西可能还没有实现,也许将来会交付。
  • 几乎所有情况都有很好的解决方法,如上例所示