使用RhinoMocks模拟参考参数

时间:2013-04-30 10:25:07

标签: c# unit-testing pass-by-reference rhino-mocks

我的代码,我有以下电话:

 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参数。


编辑: This branch of RhinoMocks使用较新版本的Castle Core,可解决此问题。作者非常友好地通过Google网上论坛通知我。

1 个答案:

答案 0 :(得分:6)

此案例的文档Rhino Mocks 3.5 Out and Ref arguments

看起来你会有像

这样的东西
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.DynamycProxy中的一个错误,它被模拟使用。

证明:
fix bug: ref & out parameter can not received if Proxied Method throw an
此修复程序将行添加到 Castle.Core / DynamicProxy / Generators / InvocationTypeGenerator.cs ,如下所示:

bool hasByRefArguments = false;

//...

if (hasByRefArguments) 
{
    invokeMethodOnTarget.CodeBuilder.AddStatement(new TryStatement());
}

//...

为Rhino.Mocks.dll添加反射器没有针对hasByRefArguments案例的额外处理(参见相同的文件InvocationTypeGenerator.cs)。