Moq - фабрика насмешек, не генерирующая новый объект с каждой итерацией
Я пытаюсь moq и проверить следующий метод:
public List<SkuCountByRetailerVm> GetSkuCountsByRetailer()
{
var viewModels = _factory.GetEmptyListOfSkuCountByRetailerVms();
foreach (var retailer in _helper.GetAllRetailersInReading())
{
var vm = _factory.GetSkuCountsByRetailerVm();
vm.Retailer = retailer;
vm.SkuCount = _helper.GetSkuCountByRetailerInReading(retailer);
viewModels.Add(vm);
}
return viewModels;
}
Класс SkuCountByRetailerVm является очень простым объектом передачи данных, он имеет свойства Retailer и SkuCount.
Тестируемый класс зависит от IFactory и IHelper, над которыми я издеваюсь в тестовом классе.
Похоже, код для тестируемого класса в порядке. Проблема при издевательстве заключается в том, что я добавляю в список 3 одинаковые модели представления (все как та, которую я ожидаю добавить как последнюю) вместо 3 разных. Я думаю, что проблема с моим тестом состоит в том, что способ, которым я настраиваю moq фабрики mockFactory.Setup(m => m.GetSkuCountsByRetailerVm()).Returns(new SkuCountByRetailerVm());
VM просто указывает на один и тот же объект, так что я бы предпочел, чтобы он каждый раз создавал новый экземпляр VM? Не уверен, что это правильный вывод, и если да, то как сделать это по-другому с Moq.
Я вставляю тестовый класс ниже, если это необходимо.
[TestInitialize]
public void Setup()
{
Mock<IReadingHelper> mockHelper = new Mock<IReadingHelper>();
Mock<IVmFactory> mockFactory = new Mock<IVmFactory>();
mockFactory.Setup(m => m.GetEmptyListOfSkuCountByRetailerVms()).Returns(new List<SkuCountByRetailerVm>());
mockFactory.Setup(m => m.GetSkuCountsByRetailerVm()).Returns(new SkuCountByRetailerVm());
mockHelper.Setup(m => m.GetAllRetailersInReading()).Returns(
new List<string> { "Fake1", "Fake2", "Fake3" });
mockHelper.Setup(m => m.GetSkuCountByRetailerInReading("Fake1")).Returns(5);
mockHelper.Setup(m => m.GetSkuCountByRetailerInReading("Fake2")).Returns(10);
mockHelper.Setup(m => m.GetSkuCountByRetailerInReading("Fake3")).Returns(15);
SkuCountByRetailerVmBuilder builder = new SkuCountByRetailerVmBuilder(mockHelper.Object, mockFactory.Object);
_vms = builder.GetSkuCountsByRetailer();
}
2 ответа
Returns
Метод имеет много перегрузок.
В настоящее время вы используете тот с подписью Returns(TResult)
где вы можете указать возвращаемое значение, а Moq использовать одно и то же значение каждый раз, когда вызывается смоделированный метод (таким образом, вы получаете один и тот же экземпляр вашего SkuCountByRetailerVm
,
Вам нужно использовать одну из перегрузок, которая занимает Func<TResult>
в качестве параметра вы можете указать функцию, которая будет вычислять значение, возвращаемое методом:
mockFactory.Setup(m => m.GetSkuCountsByRetailerVm())
.Returns(() => new SkuCountByRetailerVm());
С этой настройкой вы будете получать разные экземпляры каждый раз, когда вызывается ваш смоделированный метод.
Также вы можете реализовать
IClonable
Интерфейс и используйте специальную копию объекта, когда захотите.
Это хороший способ имитировать последовательности для повторных запросов к сетям или базам данных.