タグ付けされた質問 「mocking」

モックと偽造は、コードまたはコンポーネントを分離して、実際に他のコンポーネントやアプリケーションの依存関係を実際に利用せずに、テスト可能なコードのユニットに対してのみユニットテストを実行できるようにする方法です。モックは、モックを検査してテストの結果を主張できるという点で偽造とは異なります。

11
(なぜ)単体テストが依存関係をテストしないことが重要ですか?
自動化されたテストの価値を理解し、問題が十分に特定されていて、良いテストケースを思いつくことができる場所ならどこでもそれを使用します。ただし、こことStackOverflowの一部の人々は、依存関係ではなくユニットのみをテストすることを強調していることに気付きました。ここでは、利益が見られません。 テストの依存関係を回避するためのモッキング/スタブ化は、テストを複雑にします。実稼働コードに人為的な柔軟性/デカップリング要件を追加して、モックをサポートします。(これは良いデザインを促進すると言う人には賛成できません。余分なコードを書いたり、依存性注入フレームワークのようなものを導入したり、コードベースに複雑さを加えて実際のユースケースなしで物事をより柔軟/プラグ可能/拡張可能/分離することは、オーバーエンジニアリングではなく、良いデザイン。) 第二に、依存関係のテストとは、どこでも使用される重要な低レベルコードが、テストを明示的に考えた人以外の入力でテストされることを意味します。依存する低レベルの機能をモックアウトせずに、高レベルの機能で単体テストを実行することで、低レベルの機能に多くのバグを発見しました。理想的には、これらは低レベル機能の単体テストで発見されたはずですが、見逃されたケースは常に発生します。 これの反対側は何ですか?単体テストが依存関係もテストしないことは本当に重要ですか?もしそうなら、なぜですか? 編集:データベース、ネットワーク、Webサービスなどの外部依存関係のモックの価値を理解できます(これを明確にする動機付けをしてくれたAnna Learに感謝します)。内部依存関係、つまり他のクラス、静的関数などに言及していました。直接的な外部依存関係はありません。

11
モックオブジェクトを使用するとき、ユニットテストで依存関係の問題をどのように検出しますか?
クラスXがあり、動作X1を検証する単体テストを作成します。Xを依存関係とするクラスAもあります。 Aの単体テストを作成するとき、Xをモックします。つまり、Aの単体テスト中に、Xのモックの動作をX1に設定(仮定)します。時間が経ち、人々はあなたのシステムを使用し、変更を必要とし、Xは進化します。Xを変更して動作X2を表示します。明らかに、Xの単体テストは失敗し、それらを調整する必要があります。 しかし、Aではどうでしょうか?Aの単体テストは、Xの動作が変更されても失敗しません(Xのモックにより)。「実際の」(変更された)Xで実行すると、Aの結果が異なることを検出する方法は? 「それは単体テストの目的ではない」という線に沿った答えを期待していますが、単体テストにはどのような価値がありますか?すべてのテストに合格したときに、重大な変更が導入されていないことを本当に伝えているだけですか?そして、あるクラスの振る舞いが(喜んでまたは不本意で)変化するとき、どのようにすべての結果を(できれば自動化された方法で)検出できますか?統合テストにもっと集中すべきではないでしょうか?

11
静的は単体テストでは普遍的に「悪」であり、そうである場合、Resharperがそれを推奨するのはなぜですか?[閉まっている]
私は、C#.NETで静的であるユニットテスト(モック/スタブ)依存関係に3つの方法しかないことを発見しました。 ほくろ TypeMock ジャストモック これらの2つが無料ではなく、1つがリリース1.0に達していないことを考えると、静的なものをモックするのは簡単ではありません。 それは静的な方法とそのような「悪」(ユニットテストの意味で)を作りますか?もしそうなら、なぜ再シャーパーは私に静的なもの、静的なものを作ることを望んでいますか?(再シャーパーも「悪」ではないと仮定します。) 明確化: メソッドのユニットテストを行い、そのメソッドが別のユニット/クラスで静的メソッドを呼び出す場合のシナリオについて説明しています。単体テストのほとんどの定義では、テスト対象のメソッドが他の単体/クラスの静的メソッドを呼び出すようにした場合、単体テストではなく、統合テストになります。(便利ですが、単体テストではありません。)

8
広範囲にモックせずにユニットテストをどのように正確に記述する必要がありますか?
私が理解しているように、ユニットテストのポイントは、コードのユニットを単独でテストすることです。この意味は: コードベースの他の場所にある無関係なコードの変更によって壊れてはなりません。 統合テスト(ヒープで破損する可能性がある)とは対照的に、テストされたユニットのバグによって破損するユニットテストは1つだけです。 これはすべて、テストされたユニットのすべての外部依存関係をモックアウトする必要があることを意味します。そして、ネットワーク、ファイルシステム、データベースなどの「外部レイヤー」だけでなく、すべての外部依存関係を意味します。 これは、事実上すべての単体テストがモックする必要があるという論理的な結論につながります。一方、モックに関するGoogleの簡単な検索では、「モッキングはコードのにおい」であると主張する記事が数多くあり、ほとんど(完全にではありませんが)回避する必要があります。 さて、質問へ。 ユニットテストはどのように適切に書かれるべきですか? それらと統合テストの間の境界線は正確にどこにありますか? アップデート1 次の擬似コードを検討してください。 class Person { constructor(calculator) {} calculate(a, b) { const sum = this.calculator.add(a, b); // do some other stuff with the `sum` } } 依存関係Person.calculateをモックせずにメソッドをテストするテストCalculator(Calculator「外の世界」にアクセスしない軽量クラスであることを考えると)は、単体テストと見なすことができますか?

3
これはMockitoのリセット方法の適切な使用ですか?
テストクラスには、よく使用されるBarオブジェクトを作成するプライベートメソッドがあります。Barコンストラクタが呼び出されますsomeMethod()私の嘲笑オブジェクトのメソッドを: private @Mock Foo mockedObject; // My mocked object ... private Bar getBar() { Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod() } 私がチェックしたいテストメソッドのいくつかでは、someMethodその特定のテストによっても呼び出されました。次のようなもの: @Test public void someTest() { Bar bar = getBar(); // do some things verify(mockedObject).someMethod(); // <--- will fail } モックされたオブジェクトがsomeMethod2回呼び出されたため、これは失敗します。私のテストメソッドが私のgetBar()メソッドの副作用を気にしたくないので、終了時にモックオブジェクトをリセットするのは合理的でしょうgetBar()か? private Bar getBar() { Bar …
68 java  mocking 

6
オブジェクトのモックが難しいシステムをテストするにはどうすればよいですか?
私は次のシステムで作業しています: Network Data Feed -> Third Party Nio Library -> My Objects via adapter pattern 最近、使用しているライブラリのバージョンを更新したときに問題が発生しました。これにより、とりわけ、タイムスタンプ(サードパーティライブラリがとして返すlong)がエポック後のミリ秒からエポック後のナノ秒に変更されました。 問題: サードパーティのライブラリのオブジェクトを模擬するテストを作成する場合、サードパーティのライブラリのオブジェクトについて間違えた場合、テストは間違っています。たとえば、タイムスタンプの精度が変更され、モックが間違ったデータを返したため、ユニットテストを変更する必要があることに気づきませんでした。これはライブラリのバグではありません。ドキュメントの何かを見逃したために発生しました。 問題は、実際のデータフィードがないと実際のデータ構造を生成できないため、これらのデータ構造に含まれるデータについて確信を持てないことです。これらのオブジェクトは大きくて複雑で、多くの異なるデータが含まれています。サードパーティライブラリのドキュメントは貧弱です。 質問: この動作をテストするためにテストを設定するにはどうすればよいですか?テスト自体は簡単に間違っている可能性があるため、この問題を単体テストで解決できるかどうかはわかりません。さらに、統合システムは大きく複雑であり、見落としがちです。たとえば、上記の状況では、タイムスタンプの処理をいくつかの場所で正しく調整していましたが、そのうちの1つが見つかりませんでした。システムはほとんど統合テストで正しいことを行っているように見えましたが、本番環境(より多くのデータがある)に展開すると、問題が明らかになりました。 現在、統合テストのプロセスがありません。テストは基本的に、ユニットテストを適切な状態に保ち、問題が発生したときにさらにテストを追加し、テストサーバーに展開して問題が正しかったことを確認してから、運用環境に展開します。モックが間違って作成されたため、このタイムスタンプの問題は単体テストに合格し、すぐに明らかな問題を引き起こさなかったため統合テストに合格しました。QA部門がありません。

2
統合テストではモックを使用しますか?
私は現在、学期プロジェクトのために、単体テストや統合テストなど、複数のタイプのテストを実行する必要があるソフトウェアテストのクラスにいます。統合テストの場合、教授は統合テストにモックとモック作成ライブラリ(EasyMockやMockitoなど)を使用すると言いました。私はかなり混乱しています。統合テストとは、クラス、モジュール、サービスなどの外部をテストすることです。複数のクラスとサービスをテストする場合、統合テストでモックとスタブを使用するのが適切なのはなぜですか?

3
テスト対象のクラスの一部を偽造しても大丈夫ですか?
クラスがあるとしましょう(不自然な例とその悪いデザインを許してください): class MyProfit { public decimal GetNewYorkRevenue(); public decimal GetNewYorkExpenses(); public decimal GetNewYorkProfit(); public decimal GetMiamiRevenue(); public decimal GetMiamiExpenses(); public decimal GetMiamiProfit(); public bool BothCitiesProfitable(); } (GetxxxRevenue()およびGetxxxExpenses()メソッドには、スタブ化された依存関係があることに注意してください) 現在、GetNewYorkProfit()とGetMiamiProfit()に依存するBothCitiesProfitable()を単体テストしています。GetNewYorkProfit()とGetMiamiProfit()をスタブしても大丈夫ですか? そうしないと、GetNewYorkProfit()とGetMiamiProfit()をBothCitiesProfitable()と同時にテストしているようです。GetxxxProfit()メソッドが正しい値を返すように、GetxxxRevenue()およびGetxxxExpenses()のスタブを設定する必要があります。 これまでのところ、内部メソッドではなく外部クラスのスタブの依存関係の例を見てきました。 そして、それが大丈夫な場合、これを行うために使用すべき特定のパターンはありますか? 更新 コアの問題を見逃しているのではないかと心配しています。これはおそらく私の貧弱な例のせいです。基本的な質問は、クラス内のメソッドが、その同じクラス内で公開されている別のメソッドに依存している場合、その他のメソッドをスタブ化しても大丈夫(または推奨)ですか? たぶん何かが欠けているかもしれませんが、クラスを分割することが常に意味があるかどうかはわかりません。おそらく、もう1つの最小限の良い例は次のとおりです。 class Person { public string FirstName() public string LastName() public string FullName() } ここで、フルネームは次のように定義されます: public string …

3
過度のモッキングが必要なため、脆弱な単体テスト
私は、チームで実装しているユニットテストに関して、ますます厄介な問題に取り組んでいます。うまく設計されていないユニットコードをレガシーコードに追加しようとしていますが、実際にテストを追加するのに苦労することはありませんが、テストの結果に苦労し始めています。 問題の例として、実行の一部として5つの他のメソッドを呼び出すメソッドがあるとしましょう。このメソッドのテストは、これらの5つのメソッドのいずれかが呼び出された結果として動作が発生することを確認することです。そのため、単体テストは1つの理由と1つの理由でのみ失敗するはずなので、これらの他の4つのメソッドを呼び出して発生する潜在的な問題を排除し、それらをモックアウトする必要があります。すばらしいです!単体テストが実行され、モックされたメソッドは無視され(その動作は他の単体テストの一部として確認できます)、検証が機能します。 しかし、新しい問題があります-単体テストには、今後、他の4つのメソッドのいずれかに対する動作とシグネチャの変更、または「親メソッド」に追加する必要のある新しいメソッドの確認方法に関する詳細な知識があります。失敗の可能性を回避するために、単体テストを変更する必要があります。 当然のことながら、より多くのメソッドがより少ない動作を達成するようにするだけで、問題を多少軽減できますが、おそらくよりエレガントなソリューションが利用できることを望んでいました。 問題をキャプチャする単体テストの例を次に示します。 簡単なメモとして、「MergeTests」は単体テストクラスであり、テストしているクラスから継承し、必要に応じて動作をオーバーライドします。これは、外部クラス/依存関係への呼び出しをオーバーライドできるようにするためにテストで使用する「パターン」です。 [TestMethod] public void VerifyMergeStopsSpinner() { var mockViewModel = new Mock<MergeTests> { CallBase = true }; var mockMergeInfo = new MergeInfo(Mock.Of<IClaim>(), Mock.Of<IClaim>(), It.IsAny<bool>()); mockViewModel.Setup(m => m.ClaimView).Returns(Mock.Of<IClaimView>); mockViewModel.Setup( m => m.TryMergeClaims(It.IsAny<Func<bool>>(), It.IsAny<IClaim>(), It.IsAny<IClaim>(), It.IsAny<bool>(), It.IsAny<bool>())); mockViewModel.Setup(m => m.GetSourceClaimAndTargetClaimByMergeState(It.IsAny<MergeState>())).Returns(mockMergeInfo); mockViewModel.Setup(m => m.SwitchToOverviewTab()); mockViewModel.Setup(m => m.IncrementSaveRequiredNotification()); mockViewModel.Setup(m => …

6
TDDの観点から、モックではなくライブエンドポイントに対してテストする場合、私は悪い人ですか?
私はTDDを宗教的に守ります。私のプロジェクトは通常、テストカバレッジが85%以上であり、意味のあるテストケースがあります。 私はHBaseで多くの作業を行っていますが、メインのクライアントインターフェイスであるHTableはモックの苦痛です。ライブエンドポイントを使用するテストを記述するよりも、ユニットテストを記述するのに3〜4倍時間がかかります。 哲学的に、モックを使用するテストは、ライブエンドポイントを使用するテストよりも優先されるべきであることを知っています。しかし、HTableのモックは深刻な痛みであり、実際のHBaseインスタンスに対するテストよりも多くの利点があるとは確信していません。 私のチームの全員がワークステーションでシングルノードHBaseインスタンスを実行し、JenkinsボックスでシングルノードHBaseインスタンスを実行しているため、可用性の問題はありません。ライブエンドポイントテストは、モックを使用するテストよりも明らかに実行に時間がかかりますが、実際には気にしません。 現在、すべてのクラスに対してライブエンドポイントテストと模擬ベースのテストを作成しています。モックを捨てたいのですが、結果として品質が低下するのは望ましくありません。 皆さんはどう思いますか?

3
モッキングにより、運用コードでの処理が導入されます
IReaderインターフェイス、IReaderインターフェイスReaderImplementationの実装、およびリーダーからのデータを消費して処理するクラスReaderConsumerを想定しています。 public interface IReader { object Read() } 実装 public class ReaderImplementation { ... public object Read() { ... } } 消費者: public class ReaderConsumer() { public string location // constructor public ReaderConsumer() { ... } // read some data public object ReadData() { IReader reader = new ReaderImplementation(this.location) data …

3
モッキングフレームワークを選択する主な要因は何ですか?
私は単体テストでオブジェクトを使い始めたいと思っています。優れたモックフレームワークがたくさんあるようです。 異なるフレームワークには異なるターゲットオーディエンスがいますか? 自分の状況に合ったフレームワークを選択する際に考慮すべき要素は何ですか?
15 mocking 


7
プライベートメソッドのユニットテストの必要性を回避する方法
私はあなたがプライベートメソッドをテストすることになっていないことを知っています、そしてそれがあなたが必要であるように見えるなら、そこに出てくるのを待っているクラスがあるかもしれません。 しかし、パブリックインターフェイスをテストできるようにするためだけに数十億のクラスを持ちたくはありません。パブリックメソッドをテストするだけで多くの依存関係をモックする必要があり、ユニットテストは多くのクラスで行われます。巨大で追跡が難しい。 パブリックメソッドをテストする場合はプライベートメソッドをモックし、プライベートメソッドをテストする場合は外部依存関係をモックすることをお勧めします。 私は夢中ですか?

1
APIクライアントとラッパーのユニットテスト
私は、開発中のAPIクライアントライブラリを単体テストするための最良の方法を見つけようとして、一周して回りました。このライブラリには、Client基本的にAPIとの1:1マッピングを持つWrapperクラスと、の上部でよりユーザーフレンドリーなインターフェイスを提供する追加のクラスがありますClient。 Wrapper --> Client --> External API 私は最初の両方に対してテストの束を書いたClientし、Wrapper効果的にちょうど彼らが前方(上で動作するものは何でもの適切な機能にそのことをテストし、Wrapper上の動作Client、およびClientHTTP接続で動作します)。しかし、インターフェイスではなくこれらのクラスの実装をテストしているように感じるので、これに不快感を覚え始めました。理論的には、クラスを別の完全に有効な実装に変更することはできましたが、呼び出されると予想されていた関数が呼び出されていないため、テストは失敗します。それは私にとって脆弱なテストのように聞こえます。 この後、クラスのインターフェースについて考えました。テストでは、クラスが実際に行う方法ではなく、クラスが実際に意図したジョブを実行することを確認する必要があります。どうすればこれを行うことができますか?最初に頭に浮かぶのは、外部APIリクエストをスタブ化することです。しかし、私は外部サービスを単純​​化しすぎることに神経質です。私が見たスタブAPIの例の多くは、定型応答を提供しているだけです。これは、コードが偽のAPIに対して正しく実行されることをテストするだけの非常に簡単な方法のようです。別の方法はサービスをモックすることです。これは実行不可能であり、実際のサービスが変更されるたびに最新の状態に維持する必要があります。 最後に、私はこれを に、プログラマーSEに関する別の回答ました。 リモートAPIクライアントの仕事は、特定の呼び出しを発行することです-これ以上でもそれ以下でもありません。したがって、そのテストでは、これらの呼び出しを発行することを確認する必要があります-これ以上でもそれ以下でもありません。 そして今、私は多かれ少なかれ確信しています-テストするとき、テストClientする必要があるのは、APIへの正しいリクエストを行うことだけです(もちろん、APIが変更される可能性は常にありますが、私のテストは合格し続けます-しかしそれは統合テストが役立つ場合)。以来Clientちょうど1:APIと1のマッピング、私の懸念は実際には適用されません別の有効な実装から変更について前に-の各メソッドの唯一の有効な実装がありますClient。 しかし、私はまだにこだわっています Wrapperクラスにます。次のオプションが表示されます。 Clientクラスをスタブ化し、適切なメソッドが呼び出されることをテストします。このように、私は上記と同じClientことをしていますが、APIの代用として扱います。これは私が始めたところに私をすぐに戻します。繰り返しになりますが、これはインターフェースではなく実装のテストの不快感を与えてくれます。のWrapper非常によく、完全に別のクライアントを使用して実施することができます。 モックを作成しますClient。ここで、モックを作成する方法を決定する必要があります。サービスの完全なモックを作成するには、多くの労力が必要になります(ライブラリ自体に行った以上の作業)。API自体はシンプルですが、サービスは非常に複雑です(基本的に、そのデータに対する操作を備えたデータストアです)。そして再び、私は私のモックを本物と同期させておく必要がありますClientます。 適切なHTTPリクエストが行われていることをテストするだけです。これはWrapper、実際のClientそれらのHTTP要求を行うためにオブジェクトをため、実際に個別にテストするわけではありません。これは少しひどい単体テストになります。 したがって、これらのソリューションのいずれにも特に満足していません。あなたならどうしますか?これについて正しい方法はありますか?

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