Adrien Rose Adrien Rose - 11 days ago 4
C# Question

How to return the actual object from a mocked object with Moq

Lets say i have this method which has been mocked:

public Comfirmation AddCustomer(Customer customer)
{
// add customer to the Database
return confirmation;
}


And the my mock is like this:

_service
.Setup(x =>x.AddCustomer(It.IsAny<Customer>))
.Returns(new Confirmation());


How can i get the confirmation onject / state from the actual method?
I know that the purpose of mocking is to isolate the external factors afecting the code behavior but i really need to get the computed result of the actual method. Because this result will be used in some other part of the test.

Answer

Moq does not execute the AddCustomer function of the class. So therefore there is no way with your current Moq setup to get the Confirmation object, that the real implementation of AddCustomer might have been created.

If you need the Confirmation as input for another test, then it its the role of the arrange part of an test to create the input parameters for the method under test.

If you approach this problem by calling the AddCustomer function, then you create a coupling of the Confirmation creation code and the code that is using the Confirmation. If the creation code changes, tests might break in other areas and it could be difficult and time consuming to debug the reason.

For integration tests this coupling is the right choice, because you want to test this interaction of two parts of your software. For unit tests I recommend to decouple AddCustomer functionality from other parts.

Another approach is to create Confirmation objects that the AddCustomer function might have been created. This can be done manually or for more complex objects, by some capture/replay approach (e.g. serializing a suitable Confirmation object from the AddCustomer function to XML or JSON and create the Confirmation object for the mock in other test by parsing the static XML or JSON string by a deserializer. E.g.

 string capturedJson = "...."; // <= JSON of a Confirmation object
 var confirmation = JsonConvert.DeserializeObject<Confirmation>(capturedJson);
 _service
    .Setup(x =>x.AddCustomer(It.IsAny<Customer>))
    .Returns(confirmation);

 target.SomeConfirmationObjectUsingFunction(_service);
Comments