为具有ref参数的方法定义Stub,其中ref值未被修改

时间:2015-08-14 08:31:04

标签: c# unit-testing mocking rhino-mocks

我正在使用一个我无法更改的界面(由于遗留原因)。接口上有方法,可以使用ref个参数。

在我的单元测试中,我希望在该接口上找出其中一种方法。至关重要的是,我想更改其中一个ref参数,但保持其他参数不变。

我可以更改我想要更改的参数,但我不知道如何告诉Rhino Mocks不要触及另一个。

这是一个失败的测试,突出了问题(请注意,实际上我在定义存根之前无法访问poco,因为这是在外部模块中实例化的):

using Rhino.Mocks;
using Rhino.Mocks.Constraints;
using NUnit.Framework;

[Test]
public void Main()
{
    var serviceMock = MockRepository.GenerateMock<IService>();

    serviceMock.Stub(x => x.DoSomething(
            ref Arg<Poco>.Ref(Rhino.Mocks.Constraints.Is.Anything(), null).Dummy, // I don't want to specify null here
            ref Arg<int>.Ref(Rhino.Mocks.Constraints.Is.Equal(1), 2).Dummy));

    Poco poco = new Poco{Data = "One"};
    int returnValue = 1;
    serviceMock.DoSomething(ref poco, ref returnValue);

    Assert.AreEqual(2, returnValue); // passes
    Assert.AreEqual("One", poco.Data); // fails
}

public class Poco
{
    public string Data { get; set; }
}

public interface IService
{
    void DoSomething(ref Poco poco, ref int returnValue);
}

2 个答案:

答案 0 :(得分:1)

替换:

serviceMock.Stub(x => x.DoSomething(
        ref Arg<Poco>.Ref(Rhino.Mocks.Constraints.Is.Anything(), null).Dummy,
        ref Arg<int>.Ref(Rhino.Mocks.Constraints.Is.Equal(1), 2).Dummy));

使用:

serviceMock.Stub(x => x.DoSomething(
                 ref Arg<Poco>.Ref(Rhino.Mocks.Constraints.Is.Anything(), poco).Dummy,
                 ref Arg<int>.Ref(Rhino.Mocks.Constraints.Is.Equal(1), 2).Dummy));

此更改将使用poco替换调用参数。然后你的测试将通过。

修改

要实现您正在寻找的行为,您必须实施自定义AbstractConstraint。此对象将记录传入的值,然后您需要在interceptor中指定WhenCalledRhinoMocks方法):

class PassValue : AbstractConstraint
{

    public Poco Obj { get; private set; }

    public override bool Eval(object obj)
    {
        Obj = (Poco)obj;

        return true;
    }

    public override string Message
    {
        get { throw new NotImplementedException(); }
    }
}

在存根声明中使用它:

var p = new PassValue();

serviceMock.Stub(x => x.DoSomething(
            ref Arg<Poco>.Ref(p, p.Obj).Dummy, 
            ref Arg<int>.Ref(Rhino.Mocks.Constraints.Is.Equal(1), 2).Dummy))
            .WhenCalled(invocation =>
            {
                invocation.Arguments[0] = p.Obj;
            });

答案 1 :(得分:0)

试试这个:

 var serviceMock = MockRepository.GenerateMock<IService>();

 var poco = new Poco { Data = "One" };

 serviceMock.Stub(x => x.DoSomething(
                ref Arg<Poco>.Ref(Rhino.Mocks.Constraints.Is.Anything(), new Poco { Data = "One" }).Dummy, // I don't want to specify null here
                ref Arg<int>.Ref(Rhino.Mocks.Constraints.Is.Equal(1), 2).Dummy));

 int returnValue = 1;
 serviceMock.DoSomething(ref poco, ref returnValue);

 Assert.AreEqual(2, returnValue); // pass
 Assert.AreEqual("One", poco.Data); // pass