Moq - 模拟工厂不会在每次迭代时生成新对象

Tur*_*uro 2 c# unit-testing mstest 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;
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

nem*_*esv 5

Returns方法有很多重载.

目前您正在使用具有签名的签名Returns(TResult),您可以在其中指定要返回的值,并且每次调用mocked方法时Moq都使用相同的值(因此您获得了相同的实例)SkuCountByRetailerVm.

你需要使用一个带有a Func<TResult>作为参数的重载,你可以指定一个函数来计算从方法返回的值:

mockFactory.Setup(m => m.GetSkuCountsByRetailerVm())
           .Returns(() => new SkuCountByRetailerVm());
Run Code Online (Sandbox Code Playgroud)

使用此设置,每次模拟方法被解析时,您将获得不同的实例.