C# 使用Moq验证对象中的列表是否正确更改
我正在尝试将Moq添加到MSTest中的测试中,以测试部分代码 我想测试的代码不起作用,它应该过滤服务检索到的数据并将其传递出去。我的代码是通过MVP模式设置的,我有以下组件。(我正在测试我的演示者)C# 使用Moq验证对象中的列表是否正确更改,c#,asp.net,unit-testing,tdd,moq,C#,Asp.net,Unit Testing,Tdd,Moq,我正在尝试将Moq添加到MSTest中的测试中,以测试部分代码 我想测试的代码不起作用,它应该过滤服务检索到的数据并将其传递出去。我的代码是通过MVP模式设置的,我有以下组件。(我正在测试我的演示者) 服务->此服务正在检索对象列表并将其放入模型中(我使用模拟(Moq)返回值) 模型->实体对象,具有一些常规属性和文档列表 查看->我的usercontrol正在实现的与演示者对话的界面。这一观点也被moq所嘲弄 Presenter->object从服务中检索模型并将此模型分配给视图的属性 //
- 服务->此服务正在检索对象列表并将其放入模型中(我使用模拟(Moq)返回值)
- 模型->实体对象,具有一些常规属性和文档列表
- 查看->我的usercontrol正在实现的与演示者对话的界面。这一观点也被moq所嘲弄
- Presenter->object从服务中检索模型并将此模型分配给视图的属性
//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);
在我的第一个工作场景中,我只是从服务中检索一个模型,演示者将其传递给视图的一个属性
//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);
我得到一个错误:
System.ArgumentException: Expression is not a property setter invocation.
我做错了什么?这不起作用,因为filteredModel.Documentos处于另一个上下文中。您的视图未收到此列表,请接收来自某个筛选方法的另一个列表 稍微改变一下你的结构,我建议创建扩展方法,并对它们进行测试。 因此,您可以简单地放置
list.FilterByName(“比利”)代码>
因此,您将创建如下内容:
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;
}
公共静态IEnumerable FilteredByName(此IEnumerable可枚举,字符串名称){
如果(!string.IsNullOrEmpty(名称)){
enumerable=可枚举。其中(s=>s.Name.ToUpperInvariant()。包含(Name.ToUpperInvariant());
}
返回可枚举;
}
我找到了自己问题的解决方案
我将verifySet替换为一个普通的断言_mockedviw.object,因此我使用存根而不是mock进行测试,这非常有效。要使用我使用的存根功能,请执行以下操作:
_mockedView.SetupAllProperties();
默认情况下,无法比较两个不同的引用对象,因此我只是手动检查属性。首先,一条建议。考虑开始使用控制反转。像Ninject这样的框架可以做到这一点:。更多信息:我们正在使用控制反转。只是暂时不在我们的测试中使用任何框架。我知道有两个不同的模型实例。然而,我希望它能够在我的测试中检查两者是否相等。