用RhinoMocks模拟引用参数



在我的代码中,我有以下调用:

 string proposed=string.Empty;
 validator.IsValid(arg0, arg1, ref proposed);

我在我的测试中存根验证器,并希望存根改变引用的proposed字符串变量的内容。我尝试在WhenCalled-Handler中设置参数的值,但这显示没有效果。

validatorStub.Stub(x => x.IsValid(arg0, arg1, ref proposed))
                                            .IgnoreArguments()
                                            .WhenCalled(invocation =>
                                            {
                                                invocation.Arguments[2] = "123456"; 
                                            }).Throw(new ValidationException(string.Empty));

这在Rhino中是可能的吗?不幸的是,我没有办法编辑这个验证器…

编辑:感谢@FireAlkazar,我明白我必须更好地说明我的测试情况:

方法代码:

public class ClassUnderTest
{
   public string Arg0{get;set;}
   public string Arg1{get;set;}
   public IValidator Validator {get;set;}
   public bool Validate()
   {
      string proposal = string.Empty;
      try
      {
         if (Validator.IsValid(Arg0, Arg1, ref proposal)) return true;
      }
      catch (ValidationException ex)
      {
         if (!string.IsNullOrEmpty(proposal))
         {
            // I want to test this section of code
         }
      }
      return false;
   }                   
}

测试代码:

[TestMethod]
public void Test_Validate_ValidatorProposes_ReturnsTrue()
{
    string arg0 = "123456789";
    string arg1 = "201208150030551ABC";
    string prop = "123456";
    ClassUnderTest testInstance = new ClassUnderTest();
    testInstance.Arg0 = arg0;
    testInstance.Arg1 = arg1;
    IValidator validatorStub = MockRepository.GenerateStub<IValidator>();
    validatorStub.Stub(x => x.IsValid(Arg<string>.Is.Equal(arg0),
                                      Arg<string>.Is.Equal(arg1),
                                      ref Arg<string>.Ref(Is.Anything(), prop).Dummy))
                 .Throw(new ValidationException(string.Empty));
    testInstance.Validator = validatorStub;
    bool actual = testInstance.Validate();
    Assert.IsFalse(actual);
}

尽管如此,当我逐步执行此操作时,我看到ValidatorStub抛出了我期望它抛出的异常,但从未设置ref参数。


EDIT:这个RhinoMocks分支使用了一个更新版本的Castle Core,它解决了这个问题。作者非常好心地通过Google Groups告诉了我这件事。

这种情况的文档Rhino mock 3.5 Out和Ref参数

看起来你会有像

这样的东西
validatorStub.Stub(x => x.IsValid(Arg<string>.Is.Anything, Arg<string>.Is.Anything, ref Arg<string>.Ref(Rhino.Mocks.Constraints.Is.Anything(), "123456").Dummy));
string testRefValue = "";
validatorStub.IsValid("1", "2", ref testRefValue);
Assert.AreEqual("123456", testRefValue);
编辑:


对你的案子进行了调查。最终的结果是否定的,在最新版本的Rhino Mocks(3.6)中不能这样做。原因是旧版Castle的一个bug。DynamycProxy,由mock使用。

证明:
修复bug: ref &如果被代理方法抛出
,则无法接收out参数。这个修复在Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.cs中添加了如下行:

bool hasByRefArguments = false;
//...
if (hasByRefArguments) 
{
    invokeMethodOnTarget.CodeBuilder.AddStatement(new TryStatement());
}
//...

为Rhino.Mocks.dll添加反射器,对于hasbyrefargarguments情况没有额外的处理(参见同一文件InvocationTypeGenerator.cs)。

最新更新