この記事は、マーク・ブラウンとマーク・トウラーによってレビューされました。 SitePointコンテンツを最高の状態にしてくれたすべてのSitePointピアレビューアに感謝します!
ユニットテストを書く際の最大の障害の1つは、自明でないコードを処理する方法です。
実際のプロジェクトでは、コードは多くの場合、テストを困難にするさまざまな操作を実行します。 ajaxリクエスト、タイマー、日付、他のブラウザ機能へのアクセス…またはデータベースは、node.jsを使用している場合は常に楽しいです。ネットワークまたはファイルアクセスもそうです。
コードでそれらを制御できないため、これらすべてをテストするのは困難です。 AJAXを使用している場合、テストが合格できるようにリクエストに応答するサーバーが必要です。 Settimeoutを使用する場合、テストは待つ必要があります。データベースまたはネットワークにも同じことが言えます。正しいデータを備えたデータベースまたはネットワークサーバーが必要です。
実生活は、多くのテストチュートリアルが見えるほど簡単ではありません。しかし、あなたは解決策があることを知っていますか?
Sinonを使用することで、些細なコードを簡単にテストすることができます!
それがどのように機能するか見てみましょう。
sinon.test()
コードをテストする場合、テスト以外の要因の影響を受けたくありません。いくつかの外部要因がテストに影響する場合、テストはより複雑になり、ランダムに失敗する可能性があります。
ajax呼び出しを行うコードをテストしたい場合、どのように行いますか?サーバーを実行し、テストに必要な正確な応答を提供する必要があります。セットアップは複雑で、執筆と実行のユニットテストを困難にします。
コードが時間に依存している場合はどうなりますか?アクションを実行する前に1秒間待っているとします。今何をすべきか?テストでSettimeoutを使用して1秒間待つことができますが、これによりテストが遅くなります。たとえば、5分間の間隔が長い場合を想像してください。おそらく、テストを実行するたびに5分待たたくないと思います。
Sinonを使用することで、これらの問題(および他の多くの問題)の両方を解決し、複雑さを排除できます。
sinonは、いわゆるテストを簡単に作成できるようにすることで、テストの複雑さを削除するのに役立ちます。
名前が示すように、テストの代役は、テストで使用されているコードスニペットの代替品です。 Ajaxの例を振り返ってみると、サーバーをセットアップするのではなく、代わりにAjaxコールをTest Stand-Inに置き換えます。時間の例では、テストの代役を使用して、「前方に移動する」ことができます。これは少し奇妙に聞こえるかもしれませんが、基本的な概念は簡単です。 JavaScriptは非常に動的であるため、あらゆる機能を採用して他のものに置き換えることができます。代役をテストすることは、このアイデアをさらに一歩進めていることです。 Sinonを使用すると、JavaScript関数をテストの代役に置き換えることができます。その後、さまざまな操作を実行するように設定して、複雑なものを簡単にすることができます。
Sinonは、テストのスタンドインを3つのタイプに分割します:
偽のタイマーは、setimeoutのトリガーなど、時間を前進させるために使用できます
最初に、Sinonをインストールする必要があります。
NPMを使用して、Sinonをインストールして、NPM
を介してSinonをインストールします
var sinon = require( 'sinon')を使用したテストでsinonコードがトラブルを引き起こす関数を呼び出すときに、通常、シノンが必要です。
ajaxの場合、$ .getまたはxmlhttprequestです。しばらくの間、関数はsetimeoutである可能性があります。データベースの場合、mongodb.findoneかもしれません。
この関数を簡単に議論することを簡単にするために、私はそれを
依存関係と呼びます。テストしている関数は、別の関数の結果に依存します。 Sinonの基本的な使用パターンは、問題のある依存関係をテストのスタンドインに置き換えることです。
ajaxをテストするとき、xmlhttprequestをajax要求をシミュレートするテストの代役に置き換えます時間をテストするとき、SettimeOutを偽のタイマーに置き換えます
スパイはシノンの最も簡単な部分であり、他の機能が構築されています。
function sinon.spyは、関数のように呼ばれることができるスパイオブジェクトを返しますが、それに作られた呼び出しに関する属性も含まれています。上記の例では、FirstCallプロパティには、渡されたパラメーターリストであるFirstCall.Argsなど、最初の呼び出しに関する情報が含まれています。
パラメーターなしでsinon.spyを呼び出すことで匿名のスパイを作成できますが、より一般的なパターンは、別の関数をスパイに置き換えることです。
var spy = sinon.spy(); //我们可以像函数一样调用间谍 spy('Hello', 'World'); //现在我们可以获取有关调用的信息 console.log(spy.firstCall.args); //输出:['Hello', 'World']
別の関数をスパイに置き換えて、前の例と同様に動作しますが、1つの重要な違いがあります。スパイの使用が終了したら、上記の例の最後の行に示すように、元の関数を復元することを忘れないでください。これがなければ、テストは異常に動作する場合があります。
Spyには、使用方法に関するさまざまな情報を提供するさまざまなプロパティがあります。 SinonのSPYドキュメントには、利用可能なすべてのオプションの完全なリストが含まれています。
var user = { ... setName: function(name){ this.name = name; } } //为 setName 函数创建一个间谍 var setNameSpy = sinon.spy(user, 'setName'); //现在,每当我们调用该函数时,间谍都会记录有关它的信息 user.setName('Darth Vader'); //我们可以通过查看间谍对象来查看 console.log(setNameSpy.callCount); //输出:1 //重要最后一步 - 删除间谍 setNameSpy.restore();
実際には、スパイを頻繁に使用することはできません。スタブが必要になる可能性が高いですが、コールバックが呼び出されることを確認するなど、スパイは便利です。
この例では、モカをテストフレームワークとして、チャイをアサーションライブラリとして使用します。これら2つについて詳しく知りたい場合は、以前の投稿:JavaScriptのMochaとChaiを使用したユニットテストを参照してください。スタブに進む前に、すぐに迂回して、シノンの主張を見てみましょう。
スパイ(およびスタブ)を使用するほとんどのテストケースでは、テストの結果を確認するための何らかの方法が必要です。
あらゆる種類のアサーションを使用して、結果を確認できます。コールバックに関する前の例では、チャイのアサート機能を使用しました。これにより、値が真の値であることが保証されます。
var spy = sinon.spy(); //我们可以像函数一样调用间谍 spy('Hello', 'World'); //现在我们可以获取有关调用的信息 console.log(spy.firstCall.args); //输出:['Hello', 'World']
これを行うことの欠点は、障害時のエラーメッセージが不明であることです。 「falseは真実ではない」などのプロンプトのみを受け取ります。ご想像のとおり、これは問題がどこにあるかを見つけるのにあまり役に立たず、テストのソースコードを調べてそれを理解する必要があります。面白くない。
この問題を解決するために、カスタムエラーメッセージをアサーションに含めることができます。
var user = { ... setName: function(name){ this.name = name; } } //为 setName 函数创建一个间谍 var setNameSpy = sinon.spy(user, 'setName'); //现在,每当我们调用该函数时,间谍都会记录有关它的信息 user.setName('Darth Vader'); //我们可以通过查看间谍对象来查看 console.log(setNameSpy.callCount); //输出:1 //重要最后一步 - 删除间谍 setNameSpy.restore();
独自の主張を使用できるのはなぜですか? このようなSinonの主張を使用すると、すぐにより良いエラーメッセージを提供できます。これは、関数のパラメーターなどのより複雑な条件を検証する必要がある場合に役立ちます。
function myFunction(condition, callback){ if(condition){ callback(); } } describe('myFunction', function() { it('should call the callback function', function() { var callback = sinon.spy(); myFunction(true, callback); assert(callback.calledOnce); }); });
sinon.assert.callededを使用して、関数が特定のパラメーターで呼び出されたことを確認できます(これはおそらく私が最も使用するものです)
スタブは、柔軟で便利なため、好ましいテストの代役です。彼らはスパイのすべての機能を持っていますが、それらは監視機能の役割以上のものであり、スタブはそれを完全に置き換えます。言い換えれば、Spyを使用する場合、元の関数はまだ実行されますが、スタブを使用する場合、実行されません。
テストを遅くして書くのが困難になるajaxまたはその他の外部呼び出しを交換します
関数出力に従って異なるコードパスをトリガーします
たとえば、
jQueryのajax関数を使用するコードがある場合、テストすることは困難です。コードは、構成するサーバーにリクエストを送信するため、使用可能にする必要があります。または、テスト環境でそれを行わないようにコードに特別なケースを追加する必要があります。これは大きなタブーです。コードにテスト固有のケースをほとんど含める必要はありません。assert(callback.calledOnce);
悪いプラクティスに目を向ける代わりに、Sinonを使用してAjax機能をスタブに置き換えることができます。これにより、テストが些細なことになります。
これは、テストするサンプル関数です。オブジェクトをパラメーターとして使用し、AJAXを介して事前定義されたURLに送信します。
var spy = sinon.spy(); //我们可以像函数一样调用间谍 spy('Hello', 'World'); //现在我们可以获取有关调用的信息 console.log(spy.firstCall.args); //输出:['Hello', 'World']
通常、これをテストすることは、AJAXコールと事前定義されたURLのために困難ですが、スタブを使用すると簡単になります。
リクエストが完了した後、SaveUserに渡されたコールバック関数が正しく呼び出されることを確認する必要があるとします。
var user = { ... setName: function(name){ this.name = name; } } //为 setName 函数创建一个间谍 var setNameSpy = sinon.spy(user, 'setName'); //现在,每当我们调用该函数时,间谍都会记录有关它的信息 user.setName('Darth Vader'); //我们可以通过查看间谍对象来查看 console.log(setNameSpy.callCount); //输出:1 //重要最后一步 - 删除间谍 setNameSpy.restore();
ここでは、Ajax関数をスタブに置き換えます。これは、リクエストが送信されず、サーバーなどは必要ないことを意味します。テストコードで何が起こっているかを完全に制御できます。
SaveUserに渡すコールバックが呼び出されることを確認したいので、Stub ried に指示します。これは、スタブがパラメーターとして渡された最初の関数を自動的に呼び出すことを意味します。これにより、リクエストが完了した後にコールバックを呼び出す$ .POSTの動作がシミュレートされます。
スタブに加えて、このテストでスパイも作成しました。通常の関数をコールバックとして使用できますが、スパイを使用すると、SinonのSinon.assert.calledonceアサーションを使用してテストの結果を簡単に検証できます。
ほとんどの場合、スタブが必要な場合は、同じ基本パターンに従うことができます。
スタブのもう1つの一般的な使用法は、特定のパラメーターセットで関数が呼び出されていることを確認することです。
たとえば、AJAX関数の場合、正しい値が送信されることを確認する必要があります。したがって、次のようなものを持つことができます
同様に、$ .post()のスタブを作成しましたが、今回はそれを設定しませんでした。このテストはコールバックを気にしないので、それを降伏させる必要はありません。
function myFunction(condition, callback){ if(condition){ callback(); } } describe('myFunction', function() { it('should call the callback function', function() { var callback = sinon.spy(); myFunction(true, callback); assert(callback.calledOnce); }); });
今回は、sinon.assert.calledwith()アサーションを使用しました。スタブを正しいパラメーターで呼び出されていることを確認する必要があるため、スタブを最初のパラメーターとして渡します。
SinonでAJAXリクエストをテストする別の方法があります。これは、Sinonの偽のxmlhttprequest機能を使用して行われます。ここでは詳細は説明しませんが、それがどのように機能するかを理解したい場合は、Sinonの偽のxmlhttprequestを使用したAjaxテストに関する私の記事をご覧ください。
シミュレーション
シミュレーションは、スタブとは異なるアプローチです。 「シミュレートされたオブジェクト」という用語を聞いたことがある場合は、それは同じことです。Sinonのシミュレーションを使用して、オブジェクト全体を置き換えて、スタブ関数と同様に動作を変更できます。
単一のオブジェクトから複数の関数をスタブする必要がある場合、それらは主に有用です。単一の関数のみを交換する必要がある場合、スタブは使いやすくなります。
シミュレーションを使用するときは注意する必要があります!彼らの力のため、テストがあまりにも多く、あまりにも多くの具体的なものを具体的にするのは簡単であり、テストを誤って脆弱にする可能性があります。
スパイやスタブとは異なり、シミュレーションには組み込みのアサーションがあります。モックオブジェクトに何が起こる必要があるかを伝え、テストの最後に検証関数を呼び出すことにより、期待される結果を事前に定義できます。
store.jsを使用してコンテンツをLocalStorageに保存し、それに関連する関数をテストすると仮定します。シミュレーションを使用して、次のようにテストするのに役立ちます。
var spy = sinon.spy(); //我们可以像函数一样调用间谍 spy('Hello', 'World'); //现在我们可以获取有关调用的信息 console.log(spy.firstCall.args); //输出:['Hello', 'World']
スタブの使用は通常、シミュレーションを使用するよりも簡単であることがわかります。まったく問題ありません。シミュレーションは注意して使用する必要があります。
を使用します
この問題を解決する2つの方法があります。コンテンツ全体をTry Catchブロックでラップできます。これにより、restore()コールを最終的にブロックに配置し、何が起こっても実行されることを確認できます。 または、より良い方法は、sinon.test()を使用してテスト機能をラップすることです
関数を使用できます。およびシミュレーション。サンドボックスを使用して作成されたテストの順調には、
可能な場合は、sinon.test()を使用する場合、エラーのためにテストスタンドアロンをクリーンアップせずに、テストがランダムに失敗し始めた問題を回避できます。 Sinonは多くの操作を実行し、それがどのように機能するかを理解するのが難しい場合があります。 Sinonがどのように機能するかについての簡単なJavaScriptの例を見てみましょう。そうすれば、それが内部でどのように機能するかをよりよく理解できます。これは、さまざまな状況でより効率的に使用するのに役立ちます。 スパイ、スタブ、シミュレーションを手動で作成することもできます。 Sinonを使用する理由は、タスクを些細なものにすることです。手動で作成することは非常に複雑ですが、Sinonが何をするかを理解するためにどのように機能するかを見てみましょう。 まず、スパイは基本的に関数ラッパーです: カスタム関数を使用してSPY機能を簡単に取得できます。しかし、Sinonのスパイは、アサーションサポートを含む、より広範な機能を提供していることに注意してください。これにより、シノンはより便利になります。 非常にシンプルなスタブを作成するには、機能を新しい関数に置き換えることができます。
Sinon.jsテスト(FAQ) sinon.jsは、JavaScriptテストでスパイ、スタブ、モックを作成するための強力なツールです。それを使用するには、最初にHTMLでスクリプトタグを使用するか、NPM経由でインストールしてプロジェクトに含める必要があります。含まれると、APIを使用して、スパイ、スタブ、モックを作成および管理できます。これらを使用して、テストしているコードを分離し、予想どおりに機能することを確認できます。 sinon.jsでスパイを作成するのは簡単です。 sinon.spy()関数を呼び出すだけです。これにより、テストで使用できるスパイ関数が返されます。 SPYはそれを呼び出す方法に関する情報を記録し、それをテストでチェックインすることができます。たとえば、スパイが何回呼び出されるか、それを呼び出すために使用されるパラメーター、およびそれが返すものを確認できます。
.throws()メソッドを使用して、スタブをエラーにすることができます。たとえば、Mystubという名前のスタブがある場合は、mystub.throws()を呼び出すことでエラーを投げることができます。デフォルトでは、これによりエラーオブジェクトがスローされますが、エラーの名前をパラメーターとして渡すことにより、エラーを特定のタイプのエラーにすることもできます。 以上がSinonチュートリアル:模擬、スパイ、スタブを使用したJavaScriptテストの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。
既存の関数をテストの代役に置き換える場合は、sinon.test()を使用します。 var user = {
...
setName: function(name){
this.name = name;
}
}
//为 setName 函数创建一个间谍
var setNameSpy = sinon.spy(user, 'setName');
//现在,每当我们调用该函数时,间谍都会记录有关它的信息
user.setName('Darth Vader');
//我们可以通过查看间谍对象来查看
console.log(setNameSpy.callCount); //输出:1
//重要最后一步 - 删除间谍
setNameSpy.restore();
sinonは魔法ではありません
var spy = sinon.spy();
//我们可以像函数一样调用间谍
spy('Hello', 'World');
//现在我们可以获取有关调用的信息
console.log(spy.firstCall.args); //输出:['Hello', 'World']
スタブはどうですか?
var user = {
...
setName: function(name){
this.name = name;
}
}
//为 setName 函数创建一个间谍
var setNameSpy = sinon.spy(user, 'setName');
//现在,每当我们调用该函数时,间谍都会记录有关它的信息
user.setName('Darth Vader');
//我们可以通过查看间谍对象来查看
console.log(setNameSpy.callCount); //输出:1
//重要最后一步 - 删除间谍
setNameSpy.restore();
フルスパイ機能
シミュレーションは、スパイとスタブの動作を単純に組み合わせて、機能をさまざまな方法で使用できるようにします。
実際のコードのテストは、複雑すぎるように見えることがあり、完全に簡単にgiveめることができます。しかし、Sinonでは、ほぼすべてのタイプのコードをテストすることが簡単になります。 sinon.jsの模擬、スパイ、スタブの違いは何ですか?
Sinon.jsでは、模擬、スパイ、スタブの用途が異なります。スパイとは、パラメーターと呼ばれるすべてのパラメーター、返品値、この値、およびスローされた例外(ある場合)を記録する関数です。これらは、関数呼び出しと応答を追跡するために使用できます。スタブはスパイに似ていますが、事前にプログラムされた動作があります。また、それらがどのように呼ばれるかについての情報を記録しますが、スパイとは異なり、メソッドの動作を制御してメソッドを強制してエラーを投げたり、特定の値を返したりできます。シミュレーションは、事前にプログラムされた動作(スタブなど)と事前にプログラムされた期待(SPYなど)を備えた誤った方法です。
javascriptでの単体テストにsinon.jsを使用する方法は?
sinon.jsでスパイを作成する方法は?
sinon.jsでスタブを作成する方法は?
Sinon.jsでスタブを作成するには、sinon.stub()関数を呼び出す必要があります。これにより、テストで使用できるスタブ関数が返されます。スタブはスパイのように振る舞い、それを呼び出す方法に関する情報を記録しますが、その動作を制御することもできます。たとえば、スタブをスローにエラーにするか、特定の値を返すことができます。
sinon.jsで模擬の作成には、sinon.mock()関数を呼び出すことが含まれます。これにより、テストで使用できる模擬オブジェクトが返されます。模擬オブジェクトはスパイのように動作し、それを呼び出す方法に関する情報を記録し、スタブに似ているため、その動作を制御できます。しかし、それはあなたがそれをどのように呼ぶかについての期待を設定することを可能にします。
sinon.jsは、JavaScriptテストフレームワークとともに使用するように設計されています。スタンドアロンテストフレームワークを提供しますが、Mocha、Jasmine、Qunitなどの他の一般的なテストフレームワークと統合することもできます。 Sinon.JSドキュメントは、これらおよびその他のテストフレームワークとの統合の例を提供します。
関数をスタブまたはスパイに置き換えた場合、スタブまたはスパイの.Restore()メソッドを呼び出すことにより、元の関数を復元できます。これは、テスト後にクリーンアップして、スタブやスパイが他のテストに影響しないことを確認する場合に役立ちます。
sinon.jsは、スパイを呼び出す方法を確認するいくつかの方法を提供します。たとえば、.calledwith()メソッドを使用して、特定のパラメーターでスパイが呼び出されたかどうかを確認できます。 .calledoncewith()メソッドを使用して、特定のパラメーターでスパイが1回だけ呼び出されたかどうかを確認することもできます。
.returns()メソッドを使用して、スタブを特定の値に戻すことができます。たとえば、Mystubという名前のスタブがある場合は、mystub.returns( 'foo')を呼び出すことで値「foo」を返すことができます。
スタブをスローする方法はエラーですか?