モッキングとは何ですか?。
モッキングとは何ですか?。
回答:
プロローグ:名詞のモックを辞書で検索すると、単語の定義の1つが模倣として作成されたものであることがわかります。
モッキングは主に単体テストで使用されます。テスト中のオブジェクトは、他の(複雑な)オブジェクトに依存している場合があります。オブジェクトの動作を分離するには、他のオブジェクトを、実際のオブジェクトの動作をシミュレートするモックに置き換えます。これは、実際のオブジェクトを単体テストに組み込むことが実用的でない場合に役立ちます。
つまり、モッキングとは、実際のオブジェクトの動作をシミュレートするオブジェクトを作成することです。
時にはあなたは区別することができますモックとは対照的に、スタブ。この件については意見の相違があるかもしれませんが、私のスタブの定義は「最小限の」シミュレーションオブジェクトです。スタブは、テスト対象のオブジェクトがテストを実行できるようにするだけの十分な動作を実装します。
モックはスタブのようなものですが、テストでは、テスト対象のオブジェクトが期待どおりにモックを呼び出すことも確認します。テストの一部は、モックが正しく使用されたことを確認することです。
例を挙げましょう:レコードを格納するための単純なメモリ内構造を実装することにより、データベースをスタブできます。次に、テスト対象のオブジェクトは、データベーススタブに対してレコードを読み書きして、テストを実行できるようにします。これにより、データベースに関連しないオブジェクトの動作をテストできます。テストを実行するためだけにデータベーススタブが含まれます。
代わりに、テスト対象のオブジェクトが特定のデータをデータベースに書き込むことを確認する場合は、データベースをモックする必要があります。次に、データベースモックに何が書き込まれたかに関するアサーションをテストに組み込みます。
他の答えは、あざけるとは何かを説明しています。さまざまな例を挙げて説明します。そして、私を信じて、それは実際にはあなたが考えるよりもはるかに簡単です。
tl; dr元のクラスのインスタンスです。他のデータが注入されているので、注入された部分のテストを回避し、クラス/関数の実装の詳細のテストのみに集中できます。
簡単な例:
class Foo {
func add (num1: Int, num2: Int) -> Int { // Line A
return num1 + num2 // Line B
}
}
let unit = Foo() // unit under test
assertEqual(unit.add(1,5),6)
ご覧のとおり、私はLineAをテストしていません。つまり、入力パラメーターを検証していません。num1、num2がIntegerかどうかを確認するための検証は行っていません。私はそれに反対することはありません。
LineB(私の実装)がモックされた値1
を与え、5
期待どおりに動作しているかどうかを確認するためだけにテストしています。
明らかに、実際の言葉では、これははるかに複雑になる可能性があります。パラメータは、Person、Addressなどのカスタムオブジェクトにすることも、実装の詳細を複数にすることもできます+
。しかし、テストのロジックは同じです。
空港のセキュリティのために電子機器のタイプとブランド名を識別するマシンを構築していると仮定します。マシンは、カメラで見たものを処理することでこれを行います。
次に、マネージャーがドアを通り、ユニットテストを行うように依頼します。
次に、開発者として、MacBook pro、Google Nexus、バナナ、iPadなどの実際のオブジェクトを1000個前に持ってきて、テストしてすべてが機能するかどうかを確認します。
しかし、同じ外観のMacBook pro(実際の内部部品はありません)またはその前にあるプラスチックバナナのような、模造オブジェクトを使用することもできます。1000の本物のラップトップや腐ったバナナへの投資から身を守ることができます。
ポイントは、バナナが偽物であるかどうかをテストしようとしているのではないということです。ラップトップが偽物であるかどうかもテストしません。あなたがやっているすべては、それが言うバナナを見たら、あなたのマシンならばテストしているnot an electronic device
とMacBookのために、それは言うプロ:Laptop, Apple
。マシンにとって、その検出の結果は、偽/偽の電子機器と実際の電子機器で同じになるはずです
上記のロジックは、実際のコードの単体テストにも適用されます。つまり、関数は、実際の入力(および相互作用)から取得した、またはモックした実際の値と同じように機能するはずです。単体テスト中に注入する値。そして、実際のバナナやMacBookを使用しないようにする方法と同じように、ユニットテスト(およびモック)を使用すると、サーバーが500、403、200などのステータスコードを返すような処理を行う必要がなくなります(強制的にサーバーが500をトリガーするのは、サーバーがダウンしているときのみですが、200はサーバーがアップしているときです。サーバーのアップとダウンを切り替える間、常に10秒間待機する必要がある場合、100に焦点を当てたテストを実行するのは困難です。したがって、代わりに、ステータスコード500、200、403などの応答を挿入/模擬し、ユニット/関数を挿入/模擬値でテストします。
iOSアプリケーションを作成していて、ネットワーク呼び出しがあるとします。あなたの仕事は、アプリケーションをテストすることです。ネットワークコールが期待どおりに機能するかどうかをテスト/識別することは、お客様の責任ではありません。これをテストするのは、他の当事者(サーバーチーム)の責任です。この(ネットワーク)依存関係を削除し、それを回避するすべてのコードを引き続きテストする必要があります。
ネットワークコールは、JSON応答でさまざまなステータスコード404、500、200、303などを返すことができます。
アプリはそれらすべてで機能すると想定しています(エラーの場合、アプリは予想されるエラーをスローする必要があります)。モックを使用して行うのは、「実際のネットワーク応答に似た架空の」ネットワーク応答(JSONファイルを含む200コードなど)を作成し、「実際のネットワーク呼び出しを行ってネットワーク応答を待つ」ことなくコードをテストすることです。すべての種類のネットワーク応答のネットワーク応答を手動でハードコード/返送し、アプリが期待どおりに機能しているかどうかを確認します。(あなたは決してそれはあなたの責任ではないため、不正なデータと200をテスト/負いません、あなたの責任でテストすることで、あなたの正しい200でアプリを、または400、500、あなたのテストの場合、あなたのアプリケーションは、右のエラーをスローした場合)
これは架空のものと同様に、架空のものを作成します。
これを行うために、元のコードを使用することはできません(元のコードには事前に応答が挿入されていませんよね?)。あなたはそれに何かを追加する必要があります。通常は必要とされないダミーのデータ(またはクラスの一部)を挿入/挿入します。
したがって、元のクラスのインスタンスを作成し、必要なもの(ここではネットワークHTTPResponse、データ、または失敗した場合は、正しいerrorString、HTTPResponseを渡します)を追加して、モックされたクラスをテストします。
一言で言えば、モックとは、テスト対象を単純化して制限し、クラスが依存するものにフィードを提供することです。この例では、ネットワーク呼び出し自体のテストを回避し、代わりに、注入された出力/応答でアプリが期待どおりに機能するかどうかをテストします- クラスをモックすることによって
言うまでもなく、各ネットワーク応答を個別にテストします。
今私がいつも頭に浮かんだ質問は、契約/エンドポイント、そして基本的に私のAPIのJSON応答は常に更新されるということでした。これを考慮した単体テストを作成するにはどうすればよいですか?
これについて詳しく説明するには、モデルにという名前のキー/フィールドが必要だとしますusername
。これをテストすると、テストに合格します。2週間後、バックエンドはキーの名前をに変更しますid
。テストはまだ成功しています。正しい?か否か?
モックを更新するのはバックエンド開発者の責任ですか?彼らが最新のモックを提供することは私たちの合意の一部であるべきですか?
上記の問題に対する答えは次のとおりです。ユニットテスト+クライアント側の開発者としての開発プロセスは、古いモック応答をキャッチする必要があります。どのように私に尋ねたら?よく答えは:
実際のアプリは、更新されたAPIを使用せずに失敗します(または失敗せず、目的の動作をしません)。したがって、失敗した場合は、開発コードに変更を加えます。これもまた、テストの失敗につながります。...これを修正する必要があります。(実際にTDDプロセスを正しく行う場合は、テストを記述しない限りフィールドに関するコードを記述しないようにします。テストが失敗し、実際の開発コードを記述してください。)
つまり、バックエンドで「モックを更新しました」と言う必要はありません。最終的には、コードの開発/デバッグによって発生します。itそれはすべて開発プロセスの一部であるためです!バックエンドが偽の応答を提供する場合、それは簡単です。
これに関する私の全体的な要点は、(更新されたモックAPI応答の取得を自動化できない場合)人間による操作が必要です。つまり、JSONを手動で更新し、値が最新であることを確認するための短い会議を行うことがプロセスの一部になります。
このセクションは、CocoaHeadミートアップグループでの緩やかな議論のおかげで書かれました。
iOS開発者のみ:
モックの非常に良い例は、Natasha Muraschevによるこの実践的なプロトコル指向の講演です。スライドを実際のビデオと同期しなくなる可能性がありますが、18:30までスキップしてください。
筆記録のこの部分が本当に好きです:
これはテスト中であるため...
get
からの関数Gettable
が呼び出されることを確認したいのです。これは、関数が返され、関数が理論的にどこからでも食品の配列を割り当てることができるためです。それが呼び出されることを確認する必要があります。
SOに関するたくさんの回答と、モックに関するWeb上の良い投稿があります。あなたが探し始めるとよいかもしれない場所の1つは、Martin Fowler Mocks Aren's Stubsによる投稿です。彼は、モッキングの多くのアイデアについて議論しています。
1つの段落で-モッキングは、依存関係に依存せずにコードのユニットのテストを可能にする特定のテクニックの1つです。一般に、モックを他のメソッドと区別するのは、コードの依存関係を置き換えるために使用されるモックオブジェクトによって期待値を設定できることです。モックオブジェクトは、コードによってどのように呼び出され、どのように応答するかを認識します。
あなたの元の質問はTypeMockについて言及していたので、以下にその答えを残しておきます。
TypeMockは、商用モックフレームワークの名前です。
RhinoMocksやMoqのような無料のモックフレームワークのすべての機能に加えて、いくつかのより強力なオプションを提供します。
TypeMockが必要かどうかは非常に議論の余地があります。無料のモッキングライブラリを使用すると、たいていのモックを作成できます。多くの人は、TypeMockが提供する機能によって、カプセル化された設計から離れることが多いと主張しています。
別の答えが述べたように、「TypeMocking」は実際には定義された概念ではありませんが、TypeMockが提供するモッキングのタイプを意味し、CLRプロファイラーを使用して実行時に.Net呼び出しをインターセプトし、オブジェクトを偽造するはるかに優れた機能を提供します(要件ではありません)インターフェースや仮想メソッドが必要など)。
モックは、実際のメソッド/オブジェクトの動作を制御された方法でシミュレートするメソッド/オブジェクトです。模擬オブジェクトは単体テストで使用されます。
多くの場合、テスト中のメソッドは、その中の他の外部サービスまたはメソッドを呼び出します。これらは依存関係と呼ばれます。モックされると、依存関係は定義したとおりに動作します。
依存関係はモックによって制御されているので、コーディングしたメソッドの動作を簡単にテストできます。これは単体テストです。
タイプをモックする目的は、テストを特定のユニットに分離するために依存関係を切断することです。スタブは単純なサロゲートですが、モックは使用を確認できるサロゲートです。モックフレームワークは、スタブとモックの生成に役立つツールです。
編集:元の文言が「タイプのモック」に言及して以来、これはTypeMockに関連しているという印象を受けました。私の経験では、一般的な用語は単に「あざける」です。TypeMockに関する以下の情報は無視してください。
TypeMock Isolatorは、ILをオンザフライで変更できるという点で、他のほとんどのモックフレームワークとは異なります。これにより、他のほとんどのフレームワークでは模倣できないタイプやインスタンスを模擬できます。これらのタイプ/インスタンスを他のフレームワークと模擬するには、独自の抽象化を提供し、これらを模擬する必要があります。
TypeMockは、クリーンなランタイム環境を犠牲にして優れた柔軟性を提供します。TypeMockがその結果を達成する方法の副作用として、TypeMockを使用すると非常に奇妙な結果が得られることがあります。
TypeMockアイソレーターモックフレームワークの使用はTypeMockingだと思います。
これは、ユニットテストで使用するモックを生成するツールであり、IoCを考慮してコードを記述する必要はありません。
モックにネットワークリクエストが含まれている場合、別の方法として、実際のテストサーバーにアクセスする方法があります。このサービスを使用して、テストの要求と応答を生成できます。http://testerurl.com/