gpt4 book ai didi

c# - 用于单元测试的域模型的接口(interface)/虚拟

转载 作者:太空宇宙 更新时间:2023-11-03 22:39:32 25 4
gpt4 key购买 nike

我正在开发一个 .Net Core Web 应用程序,该应用程序正在使用 NUnit 和 Moq 进行单元测试。出于问题的目的,下面的示例非常简化。

我有一个“purchaseOrderService”类,它从存储库中获取采购订单并调用

purchaseOrder.Cancel();

在保存到存储库之前。 PurchaseOrder 和 StockItem 类如下,

public class PurchaseOrder
{
public int Id { get; set; }

public List<StockItem> StockItems { get; set; }

public PurchaseOrderStatus Status { get; private set; }

public void Cancel()
{
Status = PurchaseOrderStatus.Cancelled;
foreach(var stockItem in StockItems)
stockItem.Cancel();
}
}

public class StockItem
{
public int Id { get; set; }

public StockItemStatus Status { get; private set; }

public void Cancel()
{
Status = StockItemStatus.Cancelled;
}
}

在我的 purchaseOrder.Cancel 方法的单元测试中,我想模拟 stockItem,这样我就可以验证 cancel cancel 方法是否为采购订单中的每个 stockItem 调用一次。

我通常会用类似的东西来实现这一点。

Mock<StockItem> mockSI = new Mock<StockItem>();
mockSI.Setup(x => x.Cancel());
mockSI.Setup( x=> x.Cancel(), Times.Once);

但是,域模型未作为接口(interface)公开,并且 Cancel 方法不是虚拟的,因此不能出于 Mock 的目的覆盖 Cancel 方法。

这给我留下了 3 个选择

  1. 将 cancel 方法设为 Virtual - 这似乎是个糟糕的主意,并且会在不需要的时候将其覆盖。

  2. 为需要模拟的域模型创建一个接口(interface) - 这似乎过分了,因为我将只为测试创建接口(interface)而没有计划让任何其他类继承该接口(interface)和我可以完全控制的类。 StackOverflow 上的多篇帖子表示,没有充分理由的领域模型接口(interface)是不好的做法。

例如, Interfaces for Rich Domain Models

  1. 将此视为更多的集成测试并测试 2 个类的协同工作

目前我倾向于让 StockItem 类实现一个接口(interface)。你会推荐什么?

最佳答案

这里不需要实现接口(interface)。

只需要重新考虑如何验证预期的行为。

在取消采购订单后检查项目的状态,这应该足以表明/验证调用了 StockItem.Cancel

[Test]
public void StockItem_Should_Cancel_When_PurchaseOrder_Cancelled() {
//Arrange
var item = new StockItem();
var purchaseOrder = new PurchaseOrder() {
StockItems = new List<StockItem> {
item
}
};

//Act
purchaseOrder.Cancel();

//Assert
item.Status.Should().Be(StockItemStatus.Cancelled);
}

关于c# - 用于单元测试的域模型的接口(interface)/虚拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53054417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com