![](/img/trans.png)
[英]Testing abstract class with Moq, without the need of defining fake implementation classes
[英]Testing a specific implementation with Moq
更新1,更多细节
我的问题很难解释,对不起......
简单的问题......你如何使用Moq测试特定的实现?
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;
}
}
没有模拟它可能看起来像(如果你不使用DI)测试:
var truckShipping = new TruckShipping();
var advancedCalculation = CalculateSomethingMore(truckShipping);
var result = DoCalc();
var expected = 18;
Assert.IsTrue(result == expected);
NUnit,FluentAssertions,MbUnit,xUnit等......没关系:)
测试:var truckShipping = Mock.Of <IShipping> ....? 我想测试TruckShipping实现。
并将其注入CalculateSomethingMore。
您使用模拟来替换 伪造的轻量级对象的实际依赖项(通常过于复杂而无法实例化)。 测试模拟对象毫无意义,因为从本质上讲,你将测试来自某些第三方库的自动生成的代码。
编辑 :
目前还不清楚你为什么要依赖于具体的实现 ,特别是考虑到你正在使用IoC并注入IShipping
。 无论如何,我认为你想要的东西可以模拟TruckShipping
,但不是TruckShipping
本身。 如果是这样,那很简单:
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);
Moq不是一个测试框架,它是一个mockinq框架,因此它不提供测试功能。
对于测试,您可以使用SharpTestEx ,例如您可以编写:
[TestMethod]
public void VerifyCostIsCorrect()
{
new TruckShipping()
.CalculateCost()
.Should("The TruckShipping implementation returns a wrong cost.").Be.EqualTo(9);
}
如果您想测试TruckShipping实现,那么您需要为TruckShipping
实现单独测试。
目前,您正在测试CalculateSomethingMore
行为,该行为应返回成本的加倍值,按运费计算。 你不关心哪个运费。 CalculateSomethingMore
责任是询问运费是否成本,并将成本加倍:
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();
您可以看到,此测试既不使用9
也不使用5
作为运费。 为什么? 因为你实际上并不关心它会有什么价值。 计算运费不是被测试的责任。
此外,您还需要另一项针对TruckShipping
实施的测试,该测试将验证TruckShipping
是否正确计算运费(这是您的运输对象的责任):
TruckShipping sut = new TruckShipping();
Assert.That(9, Is.EqualTo(sut.DoCalc());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.