2012-02-28 7 views
1

私は単体テストが好きですが、それは去年一生懸命価値があることを証明しています。しかし、私はいつも問題を抱えています。ユニットテスト:プライベートメソッドとリファクタリング方法

私はそれらをパブリックにしたり、内部の属性を表示することは望ましくありません。私はきれいで鮮明なソリューションを求めています。それはテスト可能で、誰かに見せてもらえることを誇りに思います。

プライベートメソッド本当にが独立してテストする必要がある場合は、別のインターフェイスに移動して関連付けを使用して呼び出しメソッドに機能を公開する必要があるという結論に至りました。私は本質的にファサードパターンであると信じています。

これは本当にこれを実行する最善の方法ですか? それ以上客観的に...私は完全に見落とされている他のアプローチはありますか?

編集:特定の言語について話していますか? 私はC#で働いています。私は抽象的なものを探していたので、問題のコードを残していました。今日それに戻って、私はそれが実際には異なる言語のためにおそらく愚かであることを理解します。

だから、いくつかのコード:

public class CopmlexClass 
{ 
    public void SomeMethod() 
    { } 

    private void workerMethod() 
    { } 
} 

再実際のIDで

public class CopmlexClass 
{ 
    public void SomeMethod() 
    { } 

    public IComplexClassWorker Worker { get; set; } 

} 

public interface IComplexClassWorker 
{ 
    void WorkerMethod();   
} 

に織り込まになるだろうが、おそらく

コンストラクタ・インジェクションを使用することを好むとさえプロパティを公開していない

私の質問は次のとおりです。それが最善の方法ですか?どのような代替バーの反射/内部が属性に見えるのですか?

+0

特定の言語について話していますか? – Neowizard

答えて

4

次の結果であることが可能で、独立してテストする必要があり、民間の方法:

  • あなたのクラスはあまりやっている - その公開方法は、全体としてユニットをテストするにはあまりにも複雑で機能を実装します、および/または
  • 特定のプライベートメソッドを呼び出す効果は、クラス外から直接検出することはできません。

どちらの場合も、通常、元のクラスのプライベートメソッドを含む別のクラスを抽出し、publicに変換して直接テスト可能にするという明確な呼び出しです。(時には挑戦的な部分は、論理的にまとまった機能性のチャンクを見つけることであり、それは有用なクラスを自分自身で作ることができるからです。最初はリファクタリングで完璧な結果を得られるとは限らない場合もあります。長期的には、新しい可能性を開くか、他の同様のコード部分に注意を喚起するか、あるいは新しいクラスが他の場所からコードビットを引き付け始め、最終的に一貫したクラスを形成する可能性がありますあなたが当初想定していたものより完全に新しいものに変わります)

別のインターフェイス/ファサードを介して私的な方法を公開することは、長期的にこの問題を解決するつもりではなく、水を混乱させるだけです。クラスには、明確かつ完全で最小限のインターフェースが必要です。プライベートメソッドを公開すると、オブジェクトの内部状態が損なわれる可能性があります。これは悪いことです。

+0

ありがとう、ありがとう。私はおそらく私がよく意味したことを説明していないでしょう。私はプライベートメソッドをいくつかの新しいインターフェイスに移動し、それをクラスとして実装し、パブリックメソッドがメインクラスのエントリポイントのコンシューマに公開しない新しいクラスのメソッドを呼び出させるようにしました。私はあなたが物事を行う方法であると疑ったことを説明していると思います。ありがとうございました...私は他の回答を求めています;) –

+0

@JohnNicholas、明確化のおかげで、今私はあなたの考えを理解しています。これは基本的に上記のExtract Classリファクタリングと同じですが、間にインターフェイスを挿入するだけです。 IMOでは、抽出されたクラスに複雑な内部状態が含まれている場合や、単体テストでモックするような依存関係がない場合を除いて、ほとんどの場合、インタフェースを省略することができます。 –

+0

悲しいことに、本当に悪いことはこの会話の前提条件です;)モックする必要がないときにインターフェイスを省略することについての良い点。おかげさまで笑、あなたを助けてくれた人! :D –

0

私たちが数年前に私たちのチームに単体テストを書き始めたのは、上で述べたルールから始めました。つまり、アセンブリのパブリックインターフェイスをテストします。

到達不能なコードを検出することが1つの利点であると予想しました。コードカバレッジツールがテストされていないコードブロックを検出すると、いずれかのテストが欠落しているか、コードに到達できず、削除する必要があります。

しかし、実際には私たちはそれに固執していません。私たちは非常にモジュラーな設計をしています - 私たちの主なソリューションには30以上のプロジェクトがあります(ほとんどの場合、ユニットテストプロジェクトに合っています)。現在は、通常、テストプロジェクトにテスト中のプロジェクトの内部へのアクセス権を与えます。

私たちは、コードカバレッジを使用して、不足しているテストや到達不能なコードを自動的に検出することはないと考えています。これは手動プロセスなので、完了しません。

+1

あなたのテストのようなサウンドは、単体テストではなく、実際には*統合テスト*です。ちょっとしたことではありません。専門用語についてはっきりわかるのは良いことです:-) –

+0

はい - あなたは絶対に正しいです!ユニットテストと呼ばれているユニットテストと呼ばれていますが、多くのユニットをまとめて、現在は166プロジェクトのソリューションで作業しています( – GarethOwen

+0

)。約20件がテストプロジェクトです。私たちは、内部の露出と同じ効果を達成するために多くの反射を使用しますが、私はそれが好きではありません;) –

関連する問題