简体   繁体   English

用RhinoMocks模拟参考参数

[英]Mocking Reference Parameter with RhinoMocks

I my code, I have the following call: 我是我的代码,我有以下电话:

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

I stub the validator in my test and want that stub to alter the content of the referenced proposed string variable. 我在测试中存根验证器,并希望该存根更改引用的proposed字符串变量的内容。 I tried setting the value of the argument in the WhenCalled-Handler, but this shows no effect. 我尝试在WhenCalled-Handler中设置参数的值,但这没有效果。

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

Is this possible with Rhino at all? Rhino完全有可能吗? Unfortunately, I have no way of editing that validator... 不幸的是,我无法编辑该验证器...

EDIT: Thanks to @FireAlkazar, I understood that I had to better illustrate my test situtation: 编辑:感谢@FireAlkazar,我知道我必须更好地说明我的测试情况:

Method Code: 方法代码:

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;
   }                   
}

Test Code: 测试代码:

[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);
}

Still, when I step through this, I see that the ValidatorStub throws the exception i expect it to throw, but never sets the ref parameter. 尽管如此,当我逐步执行此操作时,我看到ValidatorStub抛出了我希望它引发的异常,但从未设置ref参数。


EDIT : This branch of RhinoMocks uses a newer version of Castle Core, which solves the issue. 编辑: RhinoMocks的此分支使用较新版本的Castle Core,从而解决了该问题。 The author was kind enough to inform me about this via Google Groups. 作者很友善,可以通过Google网上论坛通知我。

Documentation for this case Rhino Mocks 3.5 Out and Ref arguments 此案例的文档Rhino Mocks 3.5 Out和Ref参数

Looks like you will have something like 看起来你会有类似的东西

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);

EDIT: 编辑:
Had an investigation on your case. 对您的案件进行了调查。 Final result is no, can't do that in latest version of Rhino Mocks(3.6). 最终结果为否,在最新版本的Rhino Mocks(3.6)中无法做到。 The reason is a bug in old version of Castle.DynamycProxy, that is used by mocks. 原因是模拟使用的旧版Castle.DynamycProxy中的错误。

Proof: 证明:
fix bug: ref & out parameter can not received if Proxied Method throw an 修复错误:如果代理方法抛出一个错误,则无法接收ref&out参数
this fix adds lines to Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.cs like this: 此修复程序向Castle.Core / DynamicProxy / Generators / InvocationTypeGenerator.cs添加行,如下所示:

bool hasByRefArguments = false;

//...

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

//...

Add in reflector for Rhino.Mocks.dll there is no extra handling for hasByRefArguments case(see same file InvocationTypeGenerator.cs). 在Rhino.Mocks.dll的反射器中添加了hasByRefArguments的情况没有额外的处理(请参见同一文件InvocationTypeGenerator.cs)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM