web-dev-qa-db-ja.com

モックを可能にするために仮想メソッドを使用する必要がありますか?

これまで、モック/偽造したいクラスへのインターフェースを作成するために使用していました。その理由は、これらのクラスには上書きする仮想メソッドがないためです。しかし、最近、仮想メソッドも使用できることがわかりました。

インターフェースではなく仮想メソッドをいつ使用すればよいですか?

将来の偽造を容易にするために、ほとんどのメソッドを仮想化する必要がありますか?

4
Lassi Autio

仮想メソッドはどのように役立ちますか?モックのアイデアは、アプリケーションからクラス完全にを取り除き、完全に異なるモッククラスをプラグインすることです。共通点は、両方が同じインターフェイスを実装することだけです。継承はゲームにまったく含まれていません。

11
gnasher729

インターフェイスを抽出するよりも、メソッドを仮想化することを好みます。パフォーマンスへの影響はごくわずかです。メソッドがデフォルトで仮想であるJavaでは、これについてそれほど心配する必要はありません。

私は、すべてのクラスが同じ名前空間に対応するインターフェースを持っているコードベースをあまりにも多く見てきました。インターフェイスの種類が抽象であるのか、単なるテストアーティファクトであるのかが分からないため、プロジェクトが混乱します。

3
mcintyre321

モックにvirtualメソッドを使用することは悪い考えだとは思いません。それは仕事のためのさらに別のツールです。

この記事 で、C#のインターフェースとデリゲートと仮想メソッドを介したモックを比較しています。ご覧のとおり、virtualメソッドオプションは、モックの可能性をサポートするためのコード変更が最小であるため、魅力的ですが、もちろんトレードオフが犠牲になります。

3
Vladimir Gaevoy

仮想メソッドとそれらのオーバーライドは、インターフェースと比較してモックを作成する良い方法ではありません。

モックを作成するには、基になるクラスを参照する必要があるためです。したがって、テストはその特定のライブラリへの参照に依存します

また、他の方法では望まない可能性があるメソッドを公開するためです。

3
Ewan

メソッドをテストするためにメソッドを仮想化する必要がある場合(つまり、ユニットテストに対応するためにクラスのパブリックAPIを純粋に拡張する場合)、クラスが実行する作業が多すぎることを示しています。

これを解決するには、クラスをリファクタリングし、公開しようとしているコードを独自のユニットに移動し、新しいユニットのインスタンスを呼び出し元のクラスに注入します。

1
richzilla