从Rhino Mocks的参数返回复杂数据类型

时间:2010-04-09 17:25:16

标签: unit-testing rhino-mocks

我正在尝试使用Rhino Mocks设置一个存根,它根据传入的参数的参数返回一个值。

示例:

//Arrange
var car = new Car();
var provider= MockRepository.GenerateStub<IDataProvider>();
provider.Stub(
    x => x.GetWheelsWithSize(Arg<int>.Is.Anything))
    .Return(new List<IWheel> {
                new Wheel { Size = ?, Make = Make.Michelin },
                new Wheel { Size = ?, Make = Make.Firestone }
            });

car.Provider = provider;

//Act
car.ReplaceTires();

//Assert that the right tire size was used when replacing the tires

问题是我希望Size是传递给方法的任何东西,因为我实际上后来声称轮子的大小合适。这并不是为了证明数据提供者明显有效,因为我将其存根,而是证明传入了正确的大小。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您可以使用Do()功能来实现动态返回值。例如:

[Test]
public void DynamicallyFakeReturnValue()
{
    var calculatorStub = MockRepository.GenerateStub<ICalculator>();
    calculatorStub.Stub(address => address.AddOne(Arg<int>.Is.Anything))
        .Do((Func<int, int>) (x => x - 1));

    Assert.That(calculatorStub.AddOne(1), Is.EqualTo(0));
}

在你的情况下,它可能是:

provider.Stub(
    x => x.GetWheelsWithSize(Arg<int>.Is.Anything))
    .Do((Func<int, List<IWheel>>) (size => new List<IWheel> {
                new Wheel { Size = size, Make = Make.Michelin },
                new Wheel { Size = size, Make = Make.Firestone }
            }));

答案 1 :(得分:1)

  

“这不是为了证明数据提供者的工作......而是为了证明这一点   传递了正确的尺寸。“

不确定它是否适用于这种特殊情况,但通常我发现通过存根间接测试这些类型的东西最容易。

不是检查存根调用的输出,而是显式指定存根的参数,然后验证返回值是否按预期使用(无论返回的实际数据如何)。如果是,那么你就知道你的存根被正确调用了。

//Arrange
var wheels = new List<IWheel>();
const int wheelSize = 17;
var car = new Car();
car.WheelSize = wheelSize;
var provider= MockRepository.GenerateStub<IDataProvider>();
provider
    .Stub(x => x.GetWheelsWithSize(wheelSize))
    .Return(wheels);    
car.Provider = provider;

//Act
car.ReplaceTires();

//Assert that the right-sized wheels from the provider were
//used when replacing the tires
Assert.That(car.Wheels, Is.SameAs(wheels));

如果在这种情况下此方法不适合您,则可以使用WhenCalled to inspect the call arguments and/or modify the return value

provider
    .Stub(x => x.GetWheelsWithSize(Arg<int>.Is.Anything))
    .WhenCalled(x => x.ReturnValue = CreateWheelsOfSize((int) x.Arguments[0]));  

在这种情况下,CreateWheelsOfSize(int)将只创建轮子列表。

希望这有帮助。