使用Moq测试特定实现

时间:2012-06-05 22:39:24

标签: c# unit-testing 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) TEST:

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。

3 个答案:

答案 0 :(得分:1)

使用伪造轻量级对象,使用模拟替换实际依赖项(通常过于复杂而无法实例化)。测试模拟对象毫无意义,因为基本上,你将测试来自某些第三方库的自动生成的代码。

修改

目前还不清楚为什么要依赖具体实现,特别是考虑到你正在使用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);

答案 1 :(得分:1)

Moq不是一个测试框架,它是一个mockinq框架,因此它不提供测试功能。

对于测试,您可以使用SharpTestEx,例如您可以写:

[TestMethod]
public void VerifyCostIsCorrect()
{
    new TruckShipping()
        .CalculateCost()
        .Should("The TruckShipping implementation returns a wrong cost.").Be.EqualTo(9);
}

答案 2 :(得分:1)

如果您想测试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());