C# UnitTest-当测试方法来自模拟时发出
我有一个类使用一个接口,它有一个void方法,看起来像这个witch现在是完全有效的方法:C# UnitTest-当测试方法来自模拟时发出,c#,unit-testing,tdd,C#,Unit Testing,Tdd,我有一个类使用一个接口,它有一个void方法,看起来像这个witch现在是完全有效的方法: public void SellGivenQuantityOfProduct(Product product, int quantity) { product.StockQuantity = product.StockQuantity - quantity; } 但是以TDD的方式工作,我开始像下面这样做,但是在我的测试方法中从未进行过计算 [TestMethod] public
public void SellGivenQuantityOfProduct(Product product, int quantity)
{
product.StockQuantity = product.StockQuantity - quantity;
}
但是以TDD的方式工作,我开始像下面这样做,但是在我的测试方法中从未进行过计算
[TestMethod]
public void Can_Sell_Given_Quantity_Of_Single_Products_Stock_Quantity()
{
var mock = new Mock<ISellBuyPipeLine>();
mock.Setup(o => o.Products).Returns(new Product[]
{
new Product() {ArticleNr = 87, StockQuantity = 10}
});
var product = mock.Object.Products.First();
var choosenProductToSell = new SellBuyProduct() {Product = product, Quantity = 5};
mock.Object.SellGivenQuantityOfProduct(product, choosenProductToSell.Quantity);
/*var test = new SellBuyPipeLine();
test.SellGivenQuantityOfProduct(product, choosenProductToSell.Quantity);*/
int expectedSellValue = product.StockQuantity;
Assert.AreEqual(5, expectedSellValue);
}
[TestMethod]
公共无效可以出售给定数量的单一产品库存数量()
{
var mock=new mock();
mock.Setup(o=>o.Products).Returns(新产品[]
{
新产品(){ArticleNr=87,StockQuantity=10}
});
var product=mock.Object.Products.First();
var choosenProductToSell=new SellBuyProduct(){Product=Product,Quantity=5};
mock.Object.SellGivenQueantyOfProduct(产品,选择ProductToSell.Quantity);
/*var测试=新的SellBuyPipeLine();
test.sellgivenqueantyofproduct(产品,选择ProductToSell.Quantity)*/
int expectedSellValue=product.StockQuantity;
Assert.AreEqual(5,expectedSellValue);
}
如果我使用的是outcommented行并直接命中持有我的方法的类,那么它就可以工作了!但是我想用模拟的
我做错了什么
我是否使用了错误的方法?如果要测试实现,请测试实现。模拟对象的方法不包含实现 您可能希望模拟
产品
,使测试方法看起来像这样:
public void Can_Sell_Given_Quantity_Of_Single_Products_Stock_Quantity()
{
// Arrange
int stockQuantity = 10;
int quantityToSell = 4;
int newQuantity = 6;
var productMock = new Mock<Product>(MockBehavior.Strict);
productMock.SetupGet(p => p.StockQuantity).Returns(stockQuantity);
productMock.SetupSet(p => p.StockQuantity = newQuantity);
var classUnderTest = new SellBuyPipeLine();
// Act
test.SellGivenQuantityOfProduct(product, quantityToSell);
// Assert
productMock.VerifySet(p => p.StockQuantity, Times.Once());
}
public void可以销售给定数量的单个产品库存数量()
{
//安排
国际库存量=10;
int quantityToSell=4;
int newQuantity=6;
var productMock=newmock(MockBehavior.Strict);
productMock.SetupGet(p=>p.StockQuantity).Returns(StockQuantity);
productMock.SetupSet(p=>p.StockQuantity=newQuantity);
var classUnderTest=新的SellBuyPipeLine();
//表演
测试。销售抗纤产品(产品,数量销售);
//断言
productMock.VerifySet(p=>p.StockQuantity,Times.Once());
}
您可以不使用,因为产品不包含任何逻辑,在这种情况下,只需实例化
新产品
,并断言其库存数量
等于新数量
除非您的产品
类包含实际的业务逻辑,否则不要模仿它。我建议尽可能在编写测试时假装愚蠢
[TestMethod]
public void Can_Sell_Given_Quantity_Of_Single_Products_Stock_Quantity()
{
var product = new Product { ArticleNr = 87, StockQuantity = 10 };
var pipeline = new SellBuyPipeLine();
pipeline.SellGivenQuantityOfProduct(product, 5);
Assert.AreEqual(5, product.StockQuantity);
}
愚蠢的(非常简单的)测试导致了愚蠢的简单生产代码,这正是您想要的
尽可能避免对调用进行严格的模拟和断言,因为这会使测试变得脆弱。Ok!我应该测试一下我推荐的台词吗?或者正确的方法是什么?SellGivenQueantyOfProduct方法在我的界面中。为什么通过接口模拟测试它是错误的?或者在我的界面中使用这个方法是错误的吗?把它放在我的产品类中会更好吗?基本上是因为你嘲笑你不想测试的东西。您正在测试SellGivenQueantyOfProduct实现。否。这只是意味着,如果你想测试一个使用
isellbuypippeline
的类,你可以模拟isellbuyppeline
。在这种情况下,我的答案完全足够了,也更简单了。所以,是的,我确实认为这是一条路要走。@CodeCaster谢谢你的回答!这是我第一次使用的方法。是的,我的方法没有任何商业逻辑。现在来回答这个问题:Witch方法是最好使用的:user bsrenzel vs user CodeCaster?您正在测试的sellgivenkuantityofproduct
方法应该包含业务逻辑。这就是你测试的开始。如果产品仅仅是一个数据传输对象,则不需要对其进行模拟。您实际模拟的是依赖项,即另一个类持有对通过构造函数注入的isellbuypippeline
实例的引用。在这种情况下,您将使用模拟对象(而不是真实对象)实例化该类。这是指商业逻辑吗?是的。但这不是重点。关键是在单元测试中只测试当前类的功能(sellbuypippeline
)。如果产品
具有主要功能,则必须确保可以模拟产品
(例如,通过提取接口并将SellBuyPipeLine
更改为依赖该接口),因此,您可以针对SellBuyPipeLine
编写测试,而无需同时测试Product
。魔鬼代言人:实现Product.StockQuantity=5
将通过此测试,但不会实现“按给定数量减少库存数量”的要求。