モックオブジェクトは一般的にどのように誤用されていますか?


15

私は最近、モックオブジェクトがしばしば誤解され、誤用されると言った記事を読みました。私が注目できる明確なモッキングアンチパターンはありますか?


あなたはこれを読んだ記事ですか?martinfowler.com/articles/mocksArentStubs.html
ケプラ

いいえ...正確なソースを思い出すことはできませんが、もしそうならここに投稿します
アルマン

私はmongodb APIをモックするためにstackoverflowのタスクに連れて行かれました。自分が書いていないクラスをモックするのは間違っていると主張するブログ投稿を指摘されました。私は実際にはこれに同意しませんが、意見はそこにあります。
ケビン

回答:


13

単純な具体的なクラスがclasses笑されるのを見るのは嫌です。たとえば、他の要素に依存しない次の単純なクラスを考えます。

public class Person
{
    private readonly string _firstName;
    private readonly string _surname;

    public Person(string firstName, string surname)
    {
        if (String.IsNullOrEmpty(firstName))
        {
            throw new ArgumentException("Must have first name");
        }

        if (String.IsNullOrEmpty(surname))
        {
            throw new ArgumentException("Must have a surname");
        }

        _firstName = firstName;
        _surname = surname;
    }

    public string Name 
    {
        get
        {
            return _firstName + " " + _surname;
        }
    }
}

このクラスに関連するテストでは、「IPerson」などのインターフェイスを引き出したり、モックしたものを使用したり、期待値を設定したりするのではなく、実際のものをインスタンス化して使用します。実際のテストを使用することにより、テストがより現実的になります(パラメーターチェックが行われ、「Name」プロパティの実際の実装が行われます)。このような単純なクラスの場合、テストを遅くしたり、確定性を低くしたり、ロジックを濁らせたりすることはありません(他のクラスをテストするときにNameが呼び出されたことを知る必要はないでしょう)-これは、モック/スタブ。

これの拡張として、モックが期待どおりに設定され、テストでモックが直接呼び出されるテストを書く人もいます。驚いたことに、テストは常に合格します...うーん...


ありがたいことに、私が使用したフレームワークをモック化することで、具体的なクラスをモック化できたため、不便な点でインターフェースを引き出すことは問題になりません。
アルマン

5
それは問題を変えません-モックできるものの技術的な制約を緩和するもの(例えば、TypeMockや動的言語のようなモックフレームワーク)を使用している場合でも、この種の単純なものは一般にモックされるべきではありません。
FinnNk

私の経験則では、データではなく振る舞いをモックすることを常にしてきました。
ardave

10

当たり前のように聞こえるかもしれませんが、実動コードではモックオブジェクトを使用しないでください!実稼働コードが特定のモックオブジェクトの特性に依存する複数の例を見てきました(MockHttpServletRequestたとえば、Springframeworkから)。


14
あなたがあなたの聖なる義務に従い、コードをDailyWTFに提出したことを願っていますか?
ケプラ

1
私の以前の仕事では、コードベースからDWTFに何かを送信することは明示的に禁止されていました。
quant_dev

9
@quant_dev:彼らは、このような政策は彼らの開発に関する怖い事を暗示していたという事実...
ジョン・フィッシャー

1
あんまり。製品を販売するためにコードベースを迅速に開発しなければならなかったスタートアップでしたが、製品が成熟し、初期設計(の不足)によってさらなる開発が妨げられたため、技術的な負債を返済するためにそれを統合およびリファクタリングし始めました。マネージャーは古いコードベースがクソであることを知っていて、リファクタリングに時間とリソースを費やしましたが、悪い評判を危険にさらしたくありませんでした。
quant_dev

ショートカットを取得するだけでは、実際には毎日のwtfを取得するには十分ではありません...
poolie

9

私の意見では、モックに対する過度のメソッド呼び出しチェックです。これは、EasyMockのようないくつかのモックフレームワークによって実施される慣行であり、以前は正確に指定されていなかったメソッド呼び出しが追加されるたびにデフォルトのモック動作が失敗するように感じます。この種の厳密なモックメソッドチェックは、コア機能が同じであるにもかかわらず、コードのごくわずかな変更によってテストスイート全体が失敗する可能性がある脆弱な設計につながる可能性があります。

これに対する解決策は、モックの代わりにスタブを使用し始めています。このテーマに関して特に啓発的な記事は、MockitoのJavadocにあります:http ://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html (「2. スタブについてはどうですか?」 )、リンク先:http : //monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/

この厳密なモッキング動作を強制するのではなく、代わりにスタブを使用するため、これまでのところMockitoでの作業を楽しんでいます。また、モックオブジェクト全体ではなく、特定のメソッドに対してメソッドチェックを強制します。そのため、テストシナリオで実際に重要なメソッドのみをチェックすることになります。

ここにいくつかの本がありますが、私はこの主題に触れて、ock笑し、一般的なことをお勧めします:

xUnitパターン

単体テストの技術:.Netの例を使用して

次世代Javaテスト:TestNGと高度な概念(この本は主にtestNGについて書かれていますが、モックについての素晴らしい章があります)


過剰なメソッド呼び出しチェックのポイントに対して+1。ただし、コインの裏側には常に、予期しないメソッド呼び出しによってメソッドの失敗が発生する部分があります。ありがたいことにMockitoには、Answer.RETURNS_SMART_NULLSこれを診断するのに役立つモックの設定があります。
Bringer128

4

私の経験ではアンチパターンはほとんどありません。

  • 状態の変更が発生する可能性があり、検証が必要なドメインクラスのモック/スタブ化。
  • モックと具体的なクラスの組み合わせと相互作用する統合テストは、統合テストの目的を無効にします。
  • 本番コードでのモックの不注意な使用(これは決して起こらないはずです)

そうでなければ、モック、特にモッキートでの私の経験は簡単でした。テストの作成と保守が非常に簡単になりました。モックを使用すると、GWTTestCaseよりもGWTビュー/プレゼンターの相互作用テストがはるかに簡単になります。


2と3は明確な問題です!(1)の簡単な例はありますか?
アルマン

2

アプリケーションの複数の層にわたってモックを使用するテストは、解読および変更が特に難しいことがわかりました。ただし、これは近年、改良されたモックフレームワークAPIによって軽減されていると思います(都合の良い場所でJMockを使用しています)。

5、6年前、EasyMockのようなAPIは強力でしたが、非常に面倒でした。多くの場合、それを利用したテストコードは、テストするコードよりも桁違いに複雑でした。当時、私はそれを非常に控えめに使用するチームに影響を与え、特にテスト専用のインターフェイスの単純な代替実装である単純な手作りのモックで間に合わせようとしました。

最近、モックAPIがそれらを利用するテストをより読みやすくするようになったので、これについての私の強い意見は柔らかくなりました。基本的に、私は自分のコード(テストを含む)を他の開発者が変更できるようにしたいのです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.