根据AAA正确使用Moq回调

时间:2010-05-06 07:23:25

标签: unit-testing moq testing

我已经创建了一个单元测试,用于在Silverlight应用程序中测试我的ViewModel类上的交互。为了能够做这个测试,我正在嘲笑服务接口,注入到ViewModel。我正在使用Moq框架进行模拟。

能够验证ViewModel中的有界对象是否正确转换,我使用了回调:


[Test]
public void SaveProposal_Will_Map_Proposal_To_WebService_Parameter()
{
 var vm = CreateNewCampaignViewModel();
 var proposal = CreateNewProposal(1, "New Proposal");

 Services.Setup(x => x.SaveProposalAsync(It.IsAny<saveProposalParam>())).Callback((saveProposalParam p) =>
 {
  Assert.That(p.plainProposal, Is.Not.Null);
  Assert.That(p.plainProposal.POrderItem.orderItemId, Is.EqualTo(1));
  Assert.That(p.plainProposal.POrderItem.orderName, Is.EqualTo("New Proposal"));
 });

 proposal.State = ObjectStates.Added;
 vm.CurrentProposal = proposal;
 vm.Save();
}

它工作正常,但是如果你注意到,使用这种机制,单元测试的Assert和Act部分已经切换了它们的部分(Assert来自代理之前)。有没有更好的方法来做到这一点,同时保留正确的AAA顺序?

1 个答案:

答案 0 :(得分:2)

我不确定您是否已更改AAA订单的语义。考虑执行测试。在Action调用它之前,不会调用您的模拟接口。因此,在执行期间,您的程序仍然遵循Arrange,Act和Assert流程。

另一种方法是使用数据注入并在您的CampaignViewModel和它使用的Web服务之间创建一个接口。然后,您可以在UnitTests中创建一个类,用于保存参数信息和Assert在该类成员/属性上,而不是使用Moq动态创建代理。

Moq不应用于模拟存储或分配。相反,使用Moq提供虚拟机制和值以允许单元测试执行。如果要求断言存储,那么请花时间创建一个可以保留您的值的类。