1

次のようなクラスがたくさんあるとしましょう...

class Foo{
  private Bar highlyCoupled = new highlyCoupled();

  public bool DoTheThing(){
    return highlyCoupled.doesTheThing();
  } 
}

リフレクションを使用して foo を開き、highlyCoupled の代わりにある種の mockHighlyCoupled を注入することは可能ですか?

この状況でなんと…

class DoubleFoo : Foo{
  public bool DoTheOtherThing(){
    return DoTheThing();
  }
}

継承されたhighlyCoupledにモックを挿入できますか?

残念ながら、リフレクションを必要としないようにコードをリファクタリングすることはできません。

4

4 に答える 4

1

確かにリフレクションとモック型を使用できますが、その型は元の型から継承する必要があります (そうでない場合、FieldInfo.SetValue は失敗します)。

void Main()
{
    var bar = new Bar();
    var type = typeof(Bar);
    // Get the type and fields of FieldInfoClass.
    var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
    fields[0].SetValue(bar, new FooMock()); // you can use new Foo() here too.
    bar.Print();
}

class Foo {
    public int i = 0;
}

class FooMock : Foo {
}

class Bar {
    private Foo foo = new Foo();

    public void Print() {
        Console.WriteLine(i);
    }
}
于 2012-04-05T14:39:23.210 に答える
1

モッキングフレームワークを使用してリファクタリングできないため、これが少し簡単になる可能性があります。例えば:

タイプモック:

var fakeType = Isolate.Fake.Instance<SomeType>();
ObjectState.SetField(fakeType, "_somePrivateField", myValue);

モク:

var fakeType = new Mock<SomeType>()
fakeType.Protected().Setup<SomeType>("_somePrivateField").Returns(myValue);

正直なところ、Moq でこれを実際に試したことはありませんが、必要なことはできると思います。

于 2012-04-05T15:26:58.353 に答える
0

リファクタリングがまったくできない (highlyCoupledプロテクトを作成する) ことができない場合は、リフレクションの使用に行き詰まっています。これにより、値をhighlyCoupled変更せずに設定できます。

于 2012-04-05T14:27:45.953 に答える
0

私は一般的にロブに同意します。依存関係をより疎結合にするためにこれをリファクタリングできない場合 (少なくともテスト プロキシのような派生クラスがデフォルト値をオーバーライドできるようにする)、その可視性にもかかわらず値を設定するリフレクションがほぼ唯一の方法です。行くことができる。

最低限できることは、依存関係を保護することです。これが現在または将来可能な場合は、次のようにします。

class Foo{
  protected Bar highlyCoupled = new highlyCoupled();

  public bool DoTheThing(){
    return highlyCoupled.doesTheThing();
  } 
}

...

//in your test suite    
class FooTestProxy:Foo
{
   public FooTestProxy(Bar testMock)
   {
      highlyCoupled = testMock;
   }   
}

//now when testing, instantiate your test proxy and pass it the mocked object
于 2012-04-05T14:35:47.783 に答える