Reputation: 3457
Here's my simplified version of unit test
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);
Note that:
outerService.Notify(testObject)
internally calls
IService.SendNotification(string testObject.Name, testObject, extraObject = null)
The above will cause the test to fail, complaining that:
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)
I don't understand, the performed invocation looks exactly like the expected invocation, what is going on here?
Ok so it is working if I call service.SendNotification
directly in the test, but it won't work if I call it via outerService
? Why?
Apologies if my question was not clear enough, here's some more details as to how the Fixture
object is configured:
Fixture fixture = new Fixture();
fixture.Customize(new AutoConfiguredMoqCustomization());
fixture.Customize(new SpecimenCustomization());
That is really about it for the details, it's hopefully not a complicated scenario I suppose.
Upvotes: 2
Views: 460
Reputation: 247571
That error occurs when you call Mock.Get
and The received mocked instance was not created by Moq
. That means that there were No setups configured
for the mocked service.
Given this simplified assumption.
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; }
}
The following test should work
//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 is now aware of the service object and can extract the mock setup from the mocked instance created above.
Realized you were using AutoFixture and after some research was able to recreate your problem. You need to customize AutoFixture to use Moq.
Check Auto-Mocking with Moq on how to do that.
The following then worked given the same assumptions stated above.
//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);
Upvotes: 1