C# 使用Moq测试特定的实现
更新1,更多详细信息 我的问题很难解释,很抱歉 简单的问题。。。 如何使用Moq测试特定的实现C# 使用Moq测试特定的实现,c#,unit-testing,moq,C#,Unit Testing,Moq,更新1,更多详细信息 我的问题很难解释,很抱歉 简单的问题。。。 如何使用Moq测试特定的实现 interface IShipping { int CalculateCost(); } class TruckShipping: IShipping { int CalculateCost() { return 9; } } class Shipping: IShipping { int CalculateCost() {
interface IShipping
{
int CalculateCost();
}
class TruckShipping: IShipping
{
int CalculateCost()
{
return 9;
}
}
class Shipping: IShipping
{
int CalculateCost()
{
return 5;
}
}
class CalculateSomethingMore
{
IShipping _shipping;
CalculateSomethingMore(IShipping shipping)
{
// Here I want the TruckShipping implementation!
_shipping = shipping;
}
DoCalc()
{
return _shipping.CalculateCost * 2;
}
}
如果没有mock,它可能看起来像(如果不使用DI)
测试:
NUnit、FluentAssertions、MbUnit、xUnit等。。没关系:)
测试:
var truckShipping=模拟的?我想测试卡车运输的实现
然后将其注入CalculateMethingMore。您可以使用mock来用伪造的轻量级对象替换真正的依赖项(通常过于复杂而无法实例化)。测试模拟对象毫无意义,因为本质上,您将测试来自某个第三方库的自动生成代码 编辑: 现在还不清楚您为什么要依赖于具体的实现,特别是考虑到您正在使用IoC和inject
IShipping
。无论如何,我想你想要的是能够模拟卡车运输的东西,而不是卡车运输本身。如果是这样,很简单:
var shippingMock = new Mock<IShipping>();
// setting up mock to return 9 makes it behave as if it was TruckShipping
shippingMock.Stub(s => s.CalculateCost()).Returns(9);
var advancedCalculation = CalculateSomethingMore(shippingMock.Object);
var result = DoCalc();
var expected = 18;
Assert.IsTrue(result == expected);
var shippingMock=new Mock();
//将mock设置为return 9会使其行为类似于卡车运输
shippingMock.Stub(s=>s.CalculateCost()).Returns(9);
var advancedCalculation=CalculatesMethingMore(shippingMock.Object);
var result=DoCalc();
预期风险值=18;
Assert.IsTrue(结果==预期值);
Moq不是一个测试框架,它是一个mockinq框架,所以它不提供测试功能
对于您可以使用的测试,例如,您可以编写:
[TestMethod]
public void VerifyCostIsCorrect()
{
new TruckShipping()
.CalculateCost()
.Should("The TruckShipping implementation returns a wrong cost.").Be.EqualTo(9);
}
如果要测试卡车运输实施,则需要对TruckShipping
实施进行单独的测试
目前,您正在测试CalculateMethingMore
的行为,该行为应返回成本的双倍值(按运费计算)。你不在乎哪一条船。CalculateMethingMore
的职责是询问运输成本,并将成本翻一番:
Mock<IShipping> shipping = new Mock<IShipping>();
shipping.Setup(s => s.CalculateCost()).Returns(10);
CalculateSomethingMore sut = new CalculateSomethingMore(shipping.Object);
Assert.That(20, Is.EqualTo(sut.DoCalc()));
shipping.VerifyAll();
那不是我正在测试的模拟对象,为什么你忽略了模拟?请参阅我更新的问题:)您想测试卡车运输实现,那么,为什么要创建模拟?测试一个模拟对象没有意义,需要mockinq来设计问题,而不必担心实现。嗨,Matteo,我的问题没有更新。。。现在请看一下。对不起,我不明白你想做什么。你想测试卡车运输,那么,为什么要使用模拟?或者你只是想要一个使用Moq而不是卡车运输类的例子?我相信你看错了我的问题。。。我想测试的不是实际的模拟对象,而是使用模拟对象的类。请参阅我更新的问题:)@Janus007:您很少在测试中使用具体的实现,尤其是在模拟框架可用的情况下。mock为您提供了一些可以模拟这些具体实现的东西,而不是其他东西。查看我的编辑,让我知道这是否是您一直在寻找的。啊,我想我现在明白了,我想我应该专注于测试一个特定的实现,而事实上,模拟应该使用相关的值进行设置。感谢您的耐心。感谢您的澄清,这有助于我理解模拟和不同的实现(这并不重要)。我将此标记为接受,因为答案最全面。@Janus007欢迎:)顺便说一句,好的做法是测试中只有一个真实对象(您正在测试)。因此,如果某些依赖项的实现发生变化,您的测试不会失败。当您期望实际值为true时,也可以简单地使用
Assert.IsTrue(result)
。
Mock<IShipping> shipping = new Mock<IShipping>();
shipping.Setup(s => s.CalculateCost()).Returns(10);
CalculateSomethingMore sut = new CalculateSomethingMore(shipping.Object);
Assert.That(20, Is.EqualTo(sut.DoCalc()));
shipping.VerifyAll();
TruckShipping sut = new TruckShipping();
Assert.That(9, Is.EqualTo(sut.DoCalc());