Допустим, у меня есть простой класс с именем MyRequestHandler, и у него есть метод с именем ProcessRequest, который просто принимает объект запроса, сопоставляет его с возвращаемым объектом и возвращает этот объект. (Это, очевидно, очень простой пример гораздо более сложного метода / теста, над которым я работаю).
public class MyRequestHandler
{
private IMapper _mapper;
public MyRequestHandler(IMapper maper)
{
_mapper = mapper;
}
public MyReturnObject ProcessRequest(MyRequestObject requestObject)
{
MyReturnObject returnObject = _mapper.Map<MyReturnObject>(requestObject);
return returnObject;
}
}
Теперь для модульного тестирования (с использованием Xunit) я хочу протестировать метод ProcessRequest, но, разумеется, мы хотим использовать метод Map для Moq:
MyRequestObject requestObject = new RequestObject()
{
RequestInt = 1,
RequestString = "Hello"
};
MyReturnObject returnObject = new MyReturnObject()
{
MyInt = 1,
MyString = "Hello"
};
Mock<IMapper> mockMapper = new Mock<IMapper>();
mockMapper.Setup(m => m.Map<MyRequestObject>(requestObject)).Returns(returnObject);
MyRequestHandler requestHandler = new MyRequestHandler(mockMapper.Object);
MyReturnObject response = requestHandler.ProcessRequest(requestObject);
Assert.Equal(returnObject.MyInt, response.MyInt);
Assert.Equal(returnObject.MyString, response.MyString);
Проблема здесь в том, что Moq возвращает (и я думаю, должно быть очевидно, что это так) ссылку на returnObject, поэтому мои Asserts всегда будут пройти, даже если мой метод должен был изменить значение до возврата объекта. Теперь я могу создать новый MyReturnObject в Moq Setup / Return и сравнить MyInt и MyString по значениям, которые я присваиваю новому, но что если это действительно сложный объект с 20 свойствами и списками объектов? Может быть, я хочу использовать AutoFixture для создания возвращаемого объекта и использовать DeepEqual для их сравнения? Это вообще возможно? Я смотрю на это неправильно, или мне нужно выполнить какое-либо клонирование в меню «Настройка / возврат», чтобы это работало?