我想在AutoFac中使用我的项目的现有模拟实例。我不想重写我的PROD代码。因此,我发现AutoFac无法正常工作。我想我缺少什么。
我尝试了以下代码。
public AboutTideEditorMockTest () {
aboutTideService = new AboutTideEditorService (iAboutTideEditorRepository.Object, exceptionLogServiceMock.Object);
aboutTideServiceWithNullParam = new AboutTideEditorService (null, exceptionLogServiceMock.Object);
}
//This is my test case
[FactWithAutomaticDisplayName]
public void Test1 () {
var cb = new ContainerBuilder ();
var studyLoaderMock = new Mock<IAboutTideEditorService> ().Object;
var studyLoaderMock1 = iAboutTideEditorRepository.Object;
var studyLoaderMock2 = exceptionLogServiceMock.Object;
cb.RegisterInstance (studyLoaderMock).As<IAboutTideEditorService> ();
cb.RegisterInstance (studyLoaderMock1).As<IAboutTideEditorRepository> ();
cb.RegisterInstance (studyLoaderMock2).As<IExceptionLogService> ();
var container = cb.Build ();
using (var scope = container.BeginLifetimeScope ()) {
var component = scope.Resolve<AboutTideEditorService> ();
responseData = component.AddAboutTideContent (applicationUser, aboutTide);
Assert.Equal (ProcessStatusEnum.Invalid, responseData.Status);
}
}
我想使用传递给“ RegisterInstance”的现有模拟实例。当我尝试调试测试用例时,我得到“ responseData”为空。我无法进入AddAboutTideContent。
答案 0 :(得分:0)
您没有设置模拟返回值,需要解析IAboutTideEditorService
而不是AboutTideEditorService
。
您还需要以不同的方式生成模拟。无需更改生产代码!
这样做:
[FactWithAutomaticDisplayName]
public void Test1() {
var cb = new ContainerBuilder();
var studyLoaderMock = new Mock<IAboutTideEditorService>();
var studyLoaderMock1 = new Mock<IAboutTideEditorRepository>(); // you don't need that when resolving only IAboutTideEditorService
var studyLoaderMock2 = new Mock<IExceptionLogService>(); // you don't need that when resolving only IAboutTideEditorService
cb.RegisterInstance(studyLoaderMock.Object).As<IAboutTideEditorService>();
cb.RegisterInstance(studyLoaderMock1.Object).As<IAboutTideEditorRepository>(); // you don't need that when resolving only IAboutTideEditorService
cb.RegisterInstance(studyLoaderMock2.Object).As<IExceptionLogService>(); // you don't need that when resolving only IAboutTideEditorService
var container = cb.Build();
studyLoaderMock
.Setup(x => x.AddAboutTideContent(It.IsAny<YourTypeHereForParameterA>,
It.IsAny<YourTypeHereForParameterB>)
.Returns(new MyResponseDataType()); // add the right types here necessary, I can't tell which types they are because I am not seeing the functions code
using (var scope = container.BeginLifetimeScope()) {
var component = scope.Resolve<IAboutTideEditorService>(); // changed to IAboutTideEditorService
responseData = component.AddAboutTideContent(applicationUser, aboutTide);
Assert.Equal(ProcessStatusEnum.Invalid, responseData.Status);
}
}
您的函数调用返回null
,因为这是Moq
= MockBehavior.Loose
的模拟的默认行为。如果要让模拟函数为非显式或显式参数返回特定值,则必须调用Setup(delegate)
和Returns(objectInstance)
或Returns(Func<ObjectType>)
。
通常,您的测试设置没有多大意义。您基本上只在Autofac-Container中注册了模拟,这使容器本身与您的测试无关。通常仅在直接针对实现而不是模拟进行测试时才需要使用IoC
进行测试。这些测试称为Integration-Tests
。
这样更有意义:
[FactWithAutomaticDisplayName]
public void Test1() {
var cb = new ContainerBuilder();
var studyLoaderMock1 = new Mock<IAboutTideEditorRepository>();that when resolving only IAboutTideEditorService
var studyLoaderMock2 = new Mock<IExceptionLogService>();
var studyLoader = new AboutTideEditorService(studyLoaderMock1.Object, studyLoaderMock2.Object);
cb.RegisterInstance(studyLoader).As<IAboutTideEditorService>();
var container = cb.Build();
// now setup the functions of studyLoaderMock1 and studyLoaderMock2
// required for your function `AddAboutTideContent` from `IAboutTideEditorService` to work.
using (var scope = container.BeginLifetimeScope()) {
var component = scope.Resolve<IAboutTideEditorService>(); // changed to IAboutTideEditorService
responseData = component.AddAboutTideContent(applicationUser, aboutTide);
Assert.Equal(ProcessStatusEnum.Invalid, responseData.Status);
}
}
请记住,这里我假设AboutTideEditorService
所需的参数顺序。有关如何使用Moq
设置模拟的更多信息,请查看here。