根据 AAA 正确使用 Moq 回调

发布于 2024-08-31 04:17:58 字数 863 浏览 2 评论 0原文

我创建了一个单元测试,用于测试 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 部分已经切换了它们的部分(断言先于行动)。有没有更好的方法来做到这一点,同时保留正确的 AAA 顺序?

I've created a unit test that tests interactions on my ViewModel class in a Silverlight application. To be able to do this test, I'm mocking the service interface, injected to the ViewModel. I'm using Moq framework to do the mocking.

to be able to verify bounded object in the ViewModel is converted properly, I've used a callback:


[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();
}

It is working fine, but if you've noticed, using this mechanism the Assert and Act part of the unit test have switched their parts (Assert comes before Acting). Is there a better way to do this, while preserving correct AAA order?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

芯好空 2024-09-07 04:17:58

我不确定您是否更改了 AAA 命令的语义。考虑测试的执行。在操作调用您的模拟接口之前,不会调用它。因此,在执行过程中,您的程序仍然遵循 Arrange、Act 和 Assert 流程。

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

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

I'm not sure that you've changed the semantics of the AAA order. Consider the execution of the test. Your mocked interface will not be called until the Action invokes it. Therefore, during execution, your program still follows the Arrange, Act, and Assert flow.

The alternative would be to use Data Injection and create an interface between your CampaignViewModel and the web service that it uses. You can then create a class in your UnitTests that saves your parameter information and Assert on that class member/property rather than use Moq to create a proxy on the fly.

Moq should not be used to simulate storage or assignment. Rather, use Moq to provide dummy mechanisms and values to allow your Unit Tests to execute. If Asserting storage is a requirement, then take the time to create a class that will hold on to your values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文