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 Интерфейс и используйте специальную копию объекта, когда захотите.

Это хороший способ имитировать последовательности для повторных запросов к сетям или базам данных.

Другие вопросы по тегам