4

私のコードでは、次の呼び出しがあります。

 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 パラメーターは設定されません。


編集: RhinoMocks のこのブランチは、問題を解決する新しいバージョンの Castle Core を使用します。著者は親切にも Google グループを通じてこのことを知らせてくれました。

4

1 に答える 1

6

このケースのドキュメントRhino Mocks 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.DynamicProxy の古いバージョンのバグです。

証明:
バグを修正: Proxied Method がスローした場合、ref & out パラメータを受信できません。
この修正により、Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.csに次のような行が追加されます。

bool hasByRefArguments = false;

//...

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

//...

Rhino.Mocks.dll のリフレクターを追加すると、hasByRefArguments ケースの追加処理はありません (同じファイル InvocationTypeGenerator.cs を参照してください)。

于 2013-04-30T11:39:33.683 に答える