使用 Moq 验证对象中的列表是否正确更改

本文关键字:是否 列表 Moq 验证 对象 使用 | 更新日期: 2023-09-27 17:56:12

我正在尝试将 Moq 添加到 MSTest 中的测试中以测试我的部分代码。

我要测试的不起作用的代码是一段代码,它应该过滤服务检索的数据并将其传递。我的代码是通过 MVP 模式设置的,我有以下组件。(我正在测试我的演示者)

    服务
  • ->此服务正在检索对象列表并将其放入模型中(我正在使用模拟 (Moq) 返回值)

  • 模型 -> 具有一些常规属性和文档列表的实体对象

  • 视图 -> 我的用户控件正在实现的用于与演示者交谈的接口。 此视图也用最小起订量模拟。

  • 表示器 ->对象,用于从服务中检索模型并将此模型分配给视图的属性。

在我的第一个工作场景中,我只是从服务中检索一个模型,表示器将其传递给视图的属性。

//Setup AccountsPayableService Mock
_mockedDocumentService = new Mock<IDocumentService>();
DocumentModel<InvoiceDocumentRow> model = new DocumentModel<InvoiceDocumentRow>();
List<InvoiceDocumentRow> invoices = new List<InvoiceDocumentRow>();
InvoiceDocumentRow row = new InvoiceDocumentRow();
row.BillingMonth = DateTime.Now;
invoices.Add(row);
model.Documents = invoices;
_mockedDocumentService.Setup(service => service.GetInvoiceDocumentList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), _user)).Returns(model);
//Setup View Mock
_mockedView = new Mock<IInvoicesView>();
//Setup Presenter to be tested
_presenter = new FooPresenter(_mockedDocumentService.Object);
_presenter.SetView(_mockedView.Object);
//Act
//These events will make the presenter do the call to the service and assign this to the view property
_mockedView.Raise(view => view.Init += null, new EventArgs());
_mockedView.Raise(view => view.FirstLoad += null, new EventArgs());
//Assert
_mockedDocumentService.Verify(aps => aps.GetInvoiceDocumentList(from, changedTo, _user), Times.Once());
_mockedView.VerifySet(view => view.DocumentList = model);

此测试运行并运行良好。

但是,我也有一个案例,演示者应该过滤它从服务返回的一些结果,并将子集分配给视图。由于某种原因,我无法让它工作。

本质上,这是完全相同的测试代码,只是在表示器上使用不同的方法,该方法从服务中检索数据,对其进行筛选,然后将其传递回视图。

当我像以前一样对视图属性进行断言时:

_mockedView.VerifySet(view => view.DocumentList.Documents = filteredModel.Documents);

我收到错误:

System.ArgumentException: Expression is not a property setter invocation.

我做错了什么?

使用 Moq 验证对象中的列表是否正确更改

这是行不通的,因为filteredModel.Documentos在另一个上下文中。您的视图未收到此消息,请接收来自某种筛选方法的另一个列表。

稍微改变一下你的结构,我会建议创建扩展方法,显然是对它们进行测试。所以你可以简单地把list.FilterByName("Billy");

因此,您将创建类似以下内容的内容:

public static IEnumerable<ObjectFromVdCruijsen> FilteredByNome(this IEnumerable<ObjectFromVdCruijsen> enumerable, string name){
    if (!string.IsNullOrEmpty(name)){
            enumerable = enumerable.Where(s => s.Name.ToUpperInvariant().Contains(name.ToUpperInvariant()));
    }
    return enumerable;
}

我找到了自己问题的解决方案。

我将验证集替换为正常的断言 _mockedviw.object,所以我使用存根而不是模拟进行测试,这运行良好。 要使用我使用的存根功能,请执行以下操作:

_mockedView.SetupAllProperties();

默认情况下无法比较 2 个不同的参考对象,所以我只是手动检查属性。