1

更新 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。

4

3 回答 3

1

您使用模拟来用伪造的轻量级对象替换真正的依赖项(通常太复杂而无法实例化) 。测试模拟对象根本没有意义,因为本质上,您将测试来自某个 3rd 方库的自动生成的代码。

编辑

目前还不清楚你为什么要依赖具体的实现,特别是考虑到你正在使用 IoC 和 inject 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);
于 2012-06-05T22:48:10.710 回答
1

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

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

[TestMethod]
public void VerifyCostIsCorrect()
{
    new TruckShipping()
        .CalculateCost()
        .Should("The TruckShipping implementation returns a wrong cost.").Be.EqualTo(9);
}
于 2012-06-05T22:58:02.413 回答
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());
于 2012-06-06T11:42:40.010 回答