模拟调用异常为 0 次,但我可以正确看到执行的调用
Exception of invocation on the mock was 0 times, but I can see performed invocations correctly
这是我的简化版单元测试
var service = Fixture.Freeze<IService>();
var outerService = Fixture.Create<OuterService>();
var testObject = Fixture.Create<TestObject>();
outerService.Notify(testObject);
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
注意:
outerService.Notify(testObject)
内部调用
IService.SendNotification(string testObject.Name, testObject, extraObject = null)
以上会导致测试失败,报错:
Expected invocation 1 time,but was 0 times:
s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null)
No setups configured.
Performed invocations:
IService.SendNotification("testObject", UnitTest.TestObject, null)
我不明白,执行的调用看起来和预期的调用完全一样,这是怎么回事?
编辑
好的,所以如果我在测试中直接调用service.SendNotification
就可以了,但是如果我通过outerService
调用它就不行了?为什么?
更新
抱歉,如果我的问题不够清楚,这里有一些关于如何配置 Fixture
对象的更多细节:
Fixture fixture = new Fixture();
fixture.Customize(new AutoConfiguredMoqCustomization());
fixture.Customize(new SpecimenCustomization());
关于细节,这确实是关于它的,希望它不是我想的复杂场景。
调用 Mock.Get
和 The received mocked instance was not created by Moq
时会发生该错误。这意味着模拟服务有 No setups configured
。
鉴于这个简化的假设。
public class OuterService {
private IService service;
public OuterService(IService service) {
this.service = service;
}
public void Notify(TestObject testObject) {
service.SendNotification(testObject.Name, testObject, extraObject: null);
}
}
public interface IService {
void SendNotification(string name, TestObject testObject, object extraObject);
}
public class TestObject {
public string Name { get; set; }
}
以下测试应该有效
//Arrange
var service = Mock.Of<IService>();
var outerService = new OuterService(service);
var testObject = new TestObject { Name = "testObject" };
//Act
outerService.Notify(testObject);
//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
Moq 现在知道服务对象并且可以从上面创建的模拟实例中提取模拟设置。
更新:
意识到您正在使用 AutoFixture,经过一些研究后能够重现您的问题。您需要自定义 AutoFixture 才能使用 Moq.
检查 Auto-Mocking with Moq 如何做到这一点。
以下假设与上述相同。
//Arrange
var fixture = new Fixture();
fixture.Customize(new Ploeh.AutoFixture.AutoMoq.AutoMoqCustomization());
var service = fixture.Freeze<IService>();
var outerService = fixture.Create<OuterService>();
var testObject = fixture.Create<TestObject>();
//Act
outerService.Notify(testObject);
//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
这是我的简化版单元测试
var service = Fixture.Freeze<IService>();
var outerService = Fixture.Create<OuterService>();
var testObject = Fixture.Create<TestObject>();
outerService.Notify(testObject);
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
注意:
outerService.Notify(testObject)
内部调用
IService.SendNotification(string testObject.Name, testObject, extraObject = null)
以上会导致测试失败,报错:
Expected invocation 1 time,but was 0 times:
s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null)
No setups configured.
Performed invocations:
IService.SendNotification("testObject", UnitTest.TestObject, null)
我不明白,执行的调用看起来和预期的调用完全一样,这是怎么回事?
编辑
好的,所以如果我在测试中直接调用service.SendNotification
就可以了,但是如果我通过outerService
调用它就不行了?为什么?
更新
抱歉,如果我的问题不够清楚,这里有一些关于如何配置 Fixture
对象的更多细节:
Fixture fixture = new Fixture();
fixture.Customize(new AutoConfiguredMoqCustomization());
fixture.Customize(new SpecimenCustomization());
关于细节,这确实是关于它的,希望它不是我想的复杂场景。
调用 Mock.Get
和 The received mocked instance was not created by Moq
时会发生该错误。这意味着模拟服务有 No setups configured
。
鉴于这个简化的假设。
public class OuterService {
private IService service;
public OuterService(IService service) {
this.service = service;
}
public void Notify(TestObject testObject) {
service.SendNotification(testObject.Name, testObject, extraObject: null);
}
}
public interface IService {
void SendNotification(string name, TestObject testObject, object extraObject);
}
public class TestObject {
public string Name { get; set; }
}
以下测试应该有效
//Arrange
var service = Mock.Of<IService>();
var outerService = new OuterService(service);
var testObject = new TestObject { Name = "testObject" };
//Act
outerService.Notify(testObject);
//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);
Moq 现在知道服务对象并且可以从上面创建的模拟实例中提取模拟设置。
更新:
意识到您正在使用 AutoFixture,经过一些研究后能够重现您的问题。您需要自定义 AutoFixture 才能使用 Moq.
检查 Auto-Mocking with Moq 如何做到这一点。
以下假设与上述相同。
//Arrange
var fixture = new Fixture();
fixture.Customize(new Ploeh.AutoFixture.AutoMoq.AutoMoqCustomization());
var service = fixture.Freeze<IService>();
var outerService = fixture.Create<OuterService>();
var testObject = fixture.Create<TestObject>();
//Act
outerService.Notify(testObject);
//Assert
Mock.Get(service).Verify(s => s.SendNotification(It.IsAny<String>(), It.IsAny<TestObject>(), null), Times.Once);