【问题标题】:Use Moq to verify if list within object is changed properly使用 Moq 验证对象内的列表是否正确更改
【发布时间】:2011-05-11 12:32:26
【问题描述】:

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

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

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

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

  • View -> 我的用户控件实现的与演示者对话的界面。这个视图也被 moq 模拟了。

  • Presenter -> 对象从服务中检索模型并将此模型分配给视图的属性。

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

//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.

我做错了什么?

【问题讨论】:

标签: c# asp.net unit-testing tdd moq


【解决方案1】:

这不起作用,因为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;
}

【讨论】:

  • 我知道模型有 2 个不同的实例。但是我希望它能够在我的测试中检查两者是否相等。
【解决方案2】:

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

我将 verifySet 替换为正常的断言 _mockedviw.object 所以我使用存根来测试而不是模拟,这工作得很好。使用我使用的存根功能:

_mockedView.SetupAllProperties();

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

【讨论】:

    猜你喜欢
    • 2012-05-23
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    相关资源
    最近更新 更多