代码之家  ›  专栏  ›  技术社区  ›  Joseph

使用Rhino模拟从参数返回复杂数据类型

  •  1
  • Joseph  · 技术社区  · 14 年前

    我试图用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
    

    问题是,我希望大小与传递到方法中的大小相同,因为稍后我实际上会断言轮子的大小是正确的。这并不是为了证明数据提供程序的工作方式是明显的,因为我把它弄坏了,而是为了证明传入了正确的大小。

    我该怎么做?

    2 回复  |  直到 14 年前
        1
  •  1
  •   David Tchepak    14 年前

    “这并不是为了证明数据提供程序工作……而是为了证明 传入了正确的大小。“

    不确定它在这个特定的情况下是否工作得那么好,但是一般来说,我发现通过存根间接地测试这些类型的东西是最容易的。

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

    //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)将只创建车轮列表。

    希望这有帮助。

        2
  •  1
  •   Elisha    14 年前

    你可以使用 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 }
                }));