为带有 ref 参数的方法定义一个存根,其中 ref 值不被修改
Define a Stub for a method with ref parameters, where ref value is not modified
我正在使用无法更改的界面(出于遗留原因)。该接口具有采用 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);
}
替换:
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
。这个对象会记录传入的值,那么需要在RhinoMocks
中指定一个interceptor
(WhenCalled
方法):
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;
});
试试这个:
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
我正在使用无法更改的界面(出于遗留原因)。该接口具有采用 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);
}
替换:
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
。这个对象会记录传入的值,那么需要在RhinoMocks
中指定一个interceptor
(WhenCalled
方法):
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;
});
试试这个:
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