Using autofac with moq
本文关键字:moq with autofac Using | 更新日期: 2023-09-27 18:14:00
我需要用特定的接口注册Autofac容器,对于这种情况,我想解决mock。
我该怎么做?
我试过:
var AppContainer = ApplicationContainer.GetApplicationContainer();
var cb = new ContainerBuilder();
cb.RegisterType<Mock<IStudyLoader>>().As<IStudyLoader>().SingleInstance();
cb.Update(AppContainer);
我不想改变我的代码来解决IStudyLoader
以外的东西,但Mock<IStudyLoader>
不能替代IStudyLoader
;例如,Mock<IStudyLoader>.Object
可以替代IStudyLoader
,但我不能注册Mock<IStudyLoader>.Object
,因为它不是类型。
请纠正我;我总觉得我错过了什么。
(我有另一个限制,我不能使用其他容器ApplicationContainer.GetApplicationContainer()
)
(我认为最好在测试时手动注入依赖项,但这次我不想改变生产代码)
我找到了解决方案,是的,这是可能的!
var AppContainer = ApplicationContainer.GetApplicationContainer();
var studyLoaderMock = new Mock<IStudyLoader>().Object;
cb.RegisterInstance(studyLoaderMock).As<IStudyLoader>();
cb.Update(AppContainer);
老问题,但是AutoFac现在从4.0.1版本开始支持Moq4并提供额外的软件包,您可以安装Autofac.Extras.Moq
Install-Package Autofac.Extras.Moq
Autofac.Extras。Moq auto安装AutoFac和Moq
你不需要创建一个容器并注册StudyLoader。它由autoface . extras . moq隐式定义。
Autofac.Extras。Moq对于嵌套依赖很有价值。你不需要注册所有的依赖关系图。只模拟SystemUnderTest SUT对象
你可以实现你的测试用例如下所示:
[TestFixture]
class StudyLoaderTest
{
[Test]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
// The AutoMock class will inject a mock IStudyLoader
// into the StudyLoader constructor
//no need to create/configure a container
var studyLoader = mock.Create<StudyLoader>();
Assert.AreEqual("hi AutoFac Moq", studyLoader.Name);
}
}
}
class StudyLoader : IStudyLoader
{
public string Name { get; set; } = "hi AutoFac Moq";
}
interface IStudyLoader
{
string Name { get; set; }
}
您正在寻找的方法称为RegisterInstance
:
var mock = ...;
var cb = new ContainerBuilder();
cb.RegisterInstance(mock.Object);
var container = cb.Build();
也就是说,已经注册了要模拟的接口的现有容器(在您的示例中是AppContainer)将无法解析实例。它将继续解析生产实例。
我强烈建议你遵循的"变通方法"是,不要在测试中涉及AppContainer,而是为你的测试构建一个量身定制的容器,这样你就可以更好地控制里面的内容。其效果是,您可以注册所需的模拟实例以及SUT。
我对autofac没有特别的经验,但是我使用过的大多数其他容器都允许注册已经创建的对象实例。因此,您可以创建mock,然后注册mock。对象作为IStudyLoader的实现。关于如何做到这一点,请参考autoface文档。
既然问了这个问题,现在有一个AutoFac.Extras.Moq
包,由AutoFac支持:
这允许您在单元测试中动态创建依赖项。