我正在开发一个.Net核心网络应用程序,它正在使用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);
但是,域模型不是作为接口公开的,Cancel方法也不是虚拟的,因此不能为了Mock的目的而覆盖Cancel方法。
这给我留下了3个选择
在StackOverflow上发表了多篇文章,称没有好的理由对域模型进行接口是不好的做法。
例如,Interfaces for Rich Domain Models
目前,我倾向于让StockItem类实现一个接口。你有什么推荐的?
发布于 2018-10-30 06:15:30
这里不需要实现接口。
只需要重新考虑如何验证预期的行为。
在取消采购订单后检查项目的状态,这应该足以指示/验证调用了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);
}
https://stackoverflow.com/questions/53054417
复制相似问题