1

だから、私はレガシーコードで効果的に働くを読んでいます。それは素晴らしく、テストされていないコードで使用しても「安全」な多くのクールなテクニックをカバーしています.

それについての私のお気に入りの部分の 1 つは、面倒な依存関係がある場合にテストする予定のクラスを拡張することを提案することです。例えば

class FooBar
{
  public List<Foo> ReadFoos()
  {
    var s=new SqlConnection(Config.SomeConntectionStirng);
    s.Read("Foo")....
  }
}

にリファクタリングされます

class FooBar
{
  public List<Foo> ReadFoos()
  {
    var s=MyConnection();
    s.Read("Foo")....
  }
  protected virtual IConnection MyConnection()
  {
    return new SqlConnection(Config.SomeConnectionString);   
  }
}

そしてそれをテストするには、次のように継承します。

class TestableFooBar : FooBar
{
  protected override IConnection MyConnection()
  {
    return new MockConnection();
  }
}

拡張クラスでテストします。

さて、私の質問です。後でリファクタリングしなくても大丈夫ですか? 私がこれを言う主な理由は、呼び出し元の API を使いにくくすることなく単体テストを行うのが一般的に難しい一部のコードに役立つ可能性があるためです。パブリック API では、できる限りシンプルにする必要があります。では、これは設計上保持しても問題ないのでしょうか?

4

1 に答える 1

5

設計の観点から言えば、「抽出してオーバーライドする」という選択は、おそらくあなたが選択するところではありませんが、機能する既存のコードを変更するか、新しい機能を追加するかの予算次第です。また、パブリック API を変更することに熱心ではないかもしれませんが、より適切な依存性注入を可能にしながら API を保持する手法があります。この本では、オーバーロードへの依存関係を提供するデフォルトのコンストラクター (以下のサンプル) であるそのような手法の 1 つについて説明していると思います。

public class Foo
{
     IDependency dependency;

     public Foo() // preserves API
          : this(new Dependency())
     {
     }

     internal Foo(IDependency dependency) 
     {
         this.dependency = dependency;
     }

注: このサンプルでは、​​2 番目のコンストラクターを internal としてマークしましたが、特にアセンブリの外部のクラスにその依存関係を提供するオプションを持たせたい場合は、public のままにしておくことができます。簡単にテストできるようにするために、内部修飾子が好きです。これは、「InternalsVisibleTo」アセンブリ属性を介して内部を単体テスト プロジェクトに公開するためです。これにより、API をきれいに保つことができますが、このような手法や内部ヘルパー クラスのテスト容易性も最大限に高めることができます。

于 2013-02-14T22:31:35.557 に答える