ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptテストツールの対決:sinon.js vs testdouble.js
単体テストの実際のコードをテストする場合、多くの状況により、テストの書き込みが困難になります。関数が呼び出されているかどうかを確認する方法は? AJAXコールをテストする方法は?または、 最近、testdouble.jsという新しいライブラリが出現しています。 Sinon.jsにセットされた同様の機能がありますが、あちこちでいくつかの違いがあることを除いて。
これは、Sinonの使用法の基本的な例です: 、
これは、「匿名」テストのスタンドイン:
から取得します。
高レベルでは、両方のライブラリが非常に似ています。しかし、実際のプロジェクトで実行する必要がある可能性のある一般的なテストタスクについてはどうでしょうか?いくつかの違いがどこに現れ始めているか見てみましょう。 最初に注意すべきことは、testdouble.jsには「スパイ」の概念がないことです。 sinon.jsを使用すると、関数呼び出しを置き換えて、関数のデフォルトの動作を維持しながら情報を取得することができますが、これはtestdouble.jsでは不可能です。関数をTestDoubleに置き換えると、常にデフォルトの動作が失われます。 および
が必要です
Sinonのスタブとアサーションにより、提供されたパラメーターを不正確にすることができます。これは、例で説明するのが最も簡単です: デフォルトでは、Sinonは関数に提供される追加のパラメーターの数を気にしません。 testdouble.jsには、デフォルトで指定された正確なパラメーターが必要です。これは設計によるものです。アイデアは、この機能にテストで指定されていない他のパラメーターが提供されている場合、これはエラーであり、テストに失敗する可能性があるということです。 任意のパラメーターはtestdouble.jsで指定できますが、これはデフォルト値ではありません。
を使用すると、動作はsinon.jsに似ています。
setTimeout
のコードを使用しますか?この時点では、を使用して、コードを交換して、テストが難しいテスト内でテストを容易にするために、コードを交換する必要があります。
キーポイント
議論されているものを簡単に理解するために、使用されている用語の簡単な概要を次に示します。これらはsinon.jsの定義であり、他の場所でわずかに異なる場合があります。
sinonには、スパイ、スタブ、モックの3つの異なるテストの代役概念があります。アイデアは、それぞれが異なる使用シナリオを表すということです。これにより、ライブラリは他の言語の人々や、Xunitテストモードなどの同じ用語を使用して本を読んだ人たちにとってより馴染みのあるものになります。しかし、一方で、これらの3つの概念は、最初に使用したときにシノンをより困難にすることもできます。
<code class="language-javascript">// 以下是查看函数调用的参数的方法:
var spy = sinon.spy(Math, 'abs');
Math.abs(-10);
console.log(spy.firstCall.args); // 输出:[ -10 ]
spy.restore();
// 以下是控制函数执行方式的方法:
var stub = sinon.stub(document, 'createElement');
stub.returns('not an html element');
var x = document.createElement('div');
console.log(x); // 输出:'not an html element'
stub.restore();</code>
対照的に、testdouble.jsはよりシンプルなAPIを選択します。スパイやスタブなどの概念を使用する代わりに、JavaScriptの開発者がtd.function
、td.object
td.replace
以下は、testdouble.jsの使用方法:<code class="language-javascript">// 以下是查看函数调用的参数的方法:
var abs = td.replace(Math, 'abs');
Math.abs(-10);
var explanation = td.explain(abs);
console.log(explanation.calls[0].args); // 输出:[ -10 ]
// 以下是控制函数执行方式的方法:
var createElement = td.replace(document, 'createElement');
td.when(createElement(td.matchers.anything())).thenReturn('not an html element');
var x = document.createElement('div');
console.log(x); // 输出:'not an html element'
// testdouble 使用一次调用重置所有测试替身,无需单独清理
td.reset();</code>
<code class="language-javascript">var x = sinon.stub();</code>
<code class="language-javascript">var x = td.function();</code>
:stub.callCount
stub.args
最大の違いの1つは、スタブの設定方法と検証が行われる方法に関連しています。 Sinonを使用すると、スタブの後にコマンドをリンクし、アサーションを使用して結果を確認できます。 testdouble.jsは、関数をどのように呼びたいか、または関数呼び出しを「リハーサル」する方法を示してください。 td.explain
<code class="language-javascript">// 我们也可以为测试替身命名
var x = td.function('hello');
x('foo', 'bar');
td.explain(x);
console.log(x);
/* 输出:
{
name: 'hello',
callCount: 1,
calls: [ { args: ['foo', 'bar'], context: undefined } ],
description: 'This test double `hello` has 0 stubbings and 1 invocations.\n\nInvocations:\n - called with `("foo", "bar")`.',
isTestDouble: true
}
*/</code>
および<code class="language-javascript">var x = sinon.stub();
x.withArgs('hello', 'world').returns(true);
var y = sinon.stub();
sinon.assert.calledWith(y, 'foo', 'bar');</code>
これにより、TestDoubleのAPIが理解しやすくなります。これは、いつでリンクできるかを知る必要がないためです。 <code class="language-javascript">var x = td.function();
td.when(x('hello', 'world')).thenReturn(true);
var y = td.function();
td.verify(y('foo', 'bar'));</code>
testdouble.js spy
しかし、これは必ずしも問題ではありません。スパイの最も一般的な使用法は、それらを使用してコールバックが呼ばれていることを確認することです。
td.function
大したことではありませんが、2つのライブラリ間のこの違いに注意することは依然として重要です。そうしないと、TestDouble.jsでより具体的な方法でスパイを使用できると予想している場合は驚くかもしれません。 <code class="language-javascript">var spy = sinon.spy();
myAsyncFunction(spy);
sinon.assert.calledOnce(spy);</code>
testdouble.jsには、より正確な入力が必要<code class="language-javascript">var spy = td.function();
myAsyncFunction(spy);
td.verify(spy());</code>
および
<code class="language-javascript">// 以下是查看函数调用的参数的方法:
var spy = sinon.spy(Math, 'abs');
Math.abs(-10);
console.log(spy.firstCall.args); // 输出:[ -10 ]
spy.restore();
// 以下是控制函数执行方式的方法:
var stub = sinon.stub(document, 'createElement');
stub.returns('not an html element');
var x = document.createElement('div');
console.log(x); // 输出:'not an html element'
stub.restore();</code>
sinon.assert.calledWithExactly
などの関数を提供しますが、ドキュメントのデフォルト値として推奨されません。 stub.withArgs
のような関数には、「正確に」バリアントもありません。 <code class="language-javascript">// 以下是查看函数调用的参数的方法:
var abs = td.replace(Math, 'abs');
Math.abs(-10);
var explanation = td.explain(abs);
console.log(explanation.calls[0].args); // 输出:[ -10 ]
// 以下是控制函数执行方式的方法:
var createElement = td.replace(document, 'createElement');
td.when(createElement(td.matchers.anything())).thenReturn('not an html element');
var x = document.createElement('div');
console.log(x); // 输出:'not an html element'
// testdouble 使用一次调用重置所有测试替身,无需单独清理
td.reset();</code>
ignoreExtraArgs: true
<code class="language-javascript">var x = sinon.stub();</code>
<code class="language-javascript">var x = td.function();</code>
Note stub.resolves
testdouble.jsのコールバックサポートはより強力ですstub.rejects
を使用して、パラメーターとして受信した最初の関数
をスタブコールにします。
stub.yields
testDouble.jsはデフォルトでノードスタイルモードになります。ここでは、コールバックは最後の
<code class="language-javascript">// 我们也可以为测试替身命名 var x = td.function('hello'); x('foo', 'bar'); td.explain(x); console.log(x); /* 输出: { name: 'hello', callCount: 1, calls: [ { args: ['foo', 'bar'], context: undefined } ], description: 'This test double `hello` has 0 stubbings and 1 invocations.\n\nInvocations:\n - called with `("foo", "bar")`.', isTestDouble: true } */</code>
TestDoubleのコールバックサポートをより強力にするのは、複数のコールバックまたは異なるコールバックでシナリオの動作を簡単に定義できることです。
<code class="language-javascript">var x = sinon.stub(); x.withArgs('hello', 'world').returns(true); var y = sinon.stub(); sinon.assert.calledWith(y, 'foo', 'bar');</code>…
を呼び出したいとします
callback1
の関数にパラメーターとして渡すことに注意してください。これにより、TestDoubleに、コールバックとして使用するパラメーターが表示されます。
<code class="language-javascript">var x = td.function(); td.when(x('hello', 'world')).thenReturn(true); var y = td.function(); td.verify(y('foo', 'bar'));</code>sinonを使用して、動作を変更することもできます:
td.callback
td.when
この場合、
を使用します。特に多くのパラメーターを備えた機能については、それを機能させるために、それを機能させるために呼び出しの特定のインデックスを提供する必要があります。
<code class="language-javascript">var spy = sinon.spy(); myAsyncFunction(spy); sinon.assert.calledOnce(spy);</code>特定の値を持つ2つのコールバックを呼び出したい場合はどうなりますか?
callsArgWith
yields
sinonでは、これは単に不可能です。複数の呼び出しを
testdouble.jsには、モジュールの交換が組み込まれています
関数を<code class="language-javascript">var spy = td.function(); myAsyncFunction(spy); td.verify(spy());</code>に置き換えることができることに加えて、TestDoubleを使用すると、モジュール全体を交換することもできます。
これは、交換する必要がある関数を直接エクスポートするモジュールがある場合に主に役立ちます。
callsArgWith
<code class="language-javascript">// 以下是查看函数调用的参数的方法: var spy = sinon.spy(Math, 'abs'); Math.abs(-10); console.log(spy.firstCall.args); // 输出:[ -10 ] spy.restore(); // 以下是控制函数执行方式的方法: var stub = sinon.stub(document, 'createElement'); stub.returns('not an html element'); var x = document.createElement('div'); console.log(x); // 输出:'not an html element' stub.restore();</code>
<code class="language-javascript">// 以下是查看函数调用的参数的方法: var abs = td.replace(Math, 'abs'); Math.abs(-10); var explanation = td.explain(abs); console.log(explanation.calls[0].args); // 输出:[ -10 ] // 以下是控制函数执行方式的方法: var createElement = td.replace(document, 'createElement'); td.when(createElement(td.matchers.anything())).thenReturn('not an html element'); var x = document.createElement('div'); console.log(x); // 输出:'not an html element' // testdouble 使用一次调用重置所有测试替身,无需单独清理 td.reset();</code>モジュールの交換について注意する必要があるもう1つのことは、testdouble.jsがモジュール全体を自動的に交換することです。ここの例のような関数のエクスポートである場合、関数を置き換えます。複数の関数を含むオブジェクトの場合、それらすべてを置き換えます。コンストラクターとES6クラスもサポートされています。 ProxyquireとRewireの両方で、何とどのように交換するかを個別に指定する必要があります。
testdouble.js sinon
エミュレーションタイマーはプラグインとして使用できますが、xmlhttprequestsとajax関数をさまざまな方法で処理する必要があります。
単純なソリューションは、使用しているAjax関数を置き換えることです
$.post
testdouble.js
または:
<code class="language-javascript">var x = td.function();</code>
通常、Sandboxおよび
メソッドを使用することをお勧めします。そうしないと、誤ってスタブやスパイを残すことができます。これにより、他のテストで問題が発生する可能性があります。これにより、トレースが困難なカスケードの障害につながる可能性があります。<code class="language-javascript">// 我们也可以为测试替身命名 var x = td.function('hello'); x('foo', 'bar'); td.explain(x); console.log(x); /* 输出: { name: 'hello', callCount: 1, calls: [ { args: ['foo', 'bar'], context: undefined } ], description: 'This test double `hello` has 0 stubbings and 1 invocations.\n\nInvocations:\n - called with `("foo", "bar")`.', isTestDouble: true } */</code>
testdouble.jsは、代役をクリーンアップしてテストする方法のみを提供します:
。推奨される方法は、
これにより、テスト後のテストのスタンドインとクリーンアップのセットアップが大幅に簡素化され、追跡が困難なエラーの可能性が低下します。 sinon.test
td.reset()
これら2つのライブラリの機能を理解しました。どちらもかなり似た機能を提供しますが、互いに異なるデザインのアイデアを持っています。それを利点と短所に分解できますか? afterEach
<code class="language-javascript">var x = td.function(); td.when(x('hello', 'world')).thenReturn(true); var y = td.function(); td.verify(y('foo', 'bar'));</code>
不利な点は、複雑さを高めることです。その柔軟性により、専門家はより多くのことを行うことができますが、特定のタスクはtestdouble.jsよりも複雑であることを意味します。また、新しい人が代役の概念をテストするためのより急な学習曲線があるかもしれません。実際、私と同じくらいそれに精通している人でさえ、
とtestDouble.jsは、よりシンプルなインターフェイスを選択しました。そのコンテンツのほとんどはかなりシンプルで使いやすく、JavaScriptにより適していると感じていますが、Sinon.jsは他の言語向けに設計されているように感じることがあります。これといくつかのデザインの原則のおかげで、初心者が開始するのは簡単であり、経験豊富なテスターでさえ、多くのタスクが簡単に完了しやすくなります。たとえば、TestDoubleは同じAPIを使用して、テストスタンドインをセットアップし、結果を検証します。また、より単純な洗浄メカニズムのために、エラーが発生しやすい場合があります。
テスト疑いのある最大の問題は、その設計原則のいくつかによって引き起こされます。たとえば、スパイが完全に不足していると、スタブよりもスパイを使用することを好む人にとっては不可能になる可能性があります。これは主に意見の問題であり、問題をまったく見つけられないかもしれません。それに加えて、testdouble.jsは更新されたライブラリですが、Sinon.jsにいくつかの深刻な競争を提供しています。
以下は、関数による比較です:
功能 | Sinon.js | testdouble.js |
---|---|---|
间谍 | 是 | 否 |
存根 | 是 | 是 |
延迟存根结果 | 否 | 是 |
模拟 | 是 | 是1 |
Promise 支持 | 是(在 2.0 中) | 是 |
时间辅助函数 | 是 | 是(通过插件) |
Ajax 辅助函数 | 是 | 否(改为替换函数) |
模块替换 | 否 | 是 |
内置断言 | 是 | 是 |
匹配器 | 是 | 是 |
自定义匹配器 | 是 | 是 |
参数捕获器 | 否2 | 是 |
代理测试替身 | 否 | 是 |
td.replace(someObject)
を使用して同様の効果を実現できます。 stub.yield
(stub.yields
と混同しないでください)を使用することにより、パラメーターキャプチャラーと同様の効果を達成できます。 sinon.jsとtestdouble.jsはどちらもかなり類似した機能セットを提供します。この点で、どちらも明らかに優れていません。
2つの最大の違いはAPIです。 Sinon.jsはおそらくもう少し長く、物事を行う方法について多くのオプションを提供しています。これはその長所と短所かもしれません。 TestDouble.jsには、よりlear的なAPIがあり、学習と使用が容易になりますが、その任意の設計により、問題があると感じる人もいます。
testdoubleの設計原則に同意しますか?もしそうなら、それを使用しない理由はありません。私は多くのプロジェクトでsinon.jsを使用していましたが、sinon.jsで行った作業の少なくとも95%を実行しており、残りの5%が簡単な回避策で行われる場合があります。
sinon.jsの使用が難しい場合、またはより「javascriptスタイルの」testdouble.jsを探している場合は、同様にあなたのためのものかもしれません。私のような人でも、シノンを使用するために多くの時間を費やしている人でさえ、私はtestdouble.jsを試してみて、あなたがそれを好きかどうかを見ることを提案する傾向があります。
しかし、testdouble.jsのいくつかの側面は、sinon.jsまたは他の経験豊富なテスターの知識を持つ人に頭痛を引き起こす可能性があります。たとえば、スパイの完全な不足が決定的な要因である可能性があります。 Sinon.jsは、依然として専門家と最も柔軟性を望んでいる人にとっては良い選択です。
実際にテストスタンドインの使用方法について詳しく知りたい場合は、無料のsinon.jsガイドをご覧ください。 Sinon.jsを使用していますが、同じテクニックとベストプラクティスをTestDouble.jsに適用することもできます。
問題はありますか?コメント?あなたはすでにtestdouble.jsを使用していますか?この記事を読んだ後、試してみることを検討しますか?以下のコメントで教えてください。
この記事は、ジェームズ・ライト、ジョーン・イン、クリスチャン・ヨハンセン、ジャスティン・サールスによってレビューされました。 SitePointコンテンツを最高の状態にしてくれたすべてのSitePointピアレビューアに感謝します!
sinon.jsとtestdouble.jsはどちらも一般的なJavaScriptテストライブラリですが、いくつかの重要な違いがあります。 Sinon.JSは、スパイ、スタブ、シミュレーションなどのリッチな機能セット、およびエミュレートタイマーとXHRのユーティリティで知られています。これは、あらゆるテストフレームワークと組み合わせて使用できる汎用性の高いツールです。一方、TestDouble.jsは、テストするシステムの部分に代わるスタンドインをテストするためのシンプルで直感的なAPIの提供に焦点を当てたミニマリストライブラリです。タイマーやXHRをエミュレートするためのユーティリティは含まれていませんが、使いやすく理解できるように設計されているため、よりlear的なテスト方法を好む人にとっては素晴らしい選択肢です。
sinon.jsおよびtestdouble.jsは、npm(node.jsパッケージマネージャー)を介してインストールできます。 sinon.jsの場合、コマンドnpm install sinon
を使用できます。 testdouble.jsの場合、コマンドはnpm install testdouble
です。インストール後、それぞれテストファイルに導入してconst sinon = require('sinon')
とconst td = require('testdouble')
を使用できます。
、 sinon.jsには、testdouble.jsと比較して、より包括的な機能セットがあります。タイマーとXHRをエミュレートするためのユーティリティが含まれています。これは、特定の種類のコードをテストするのに非常に役立ちます。また、より広く使用されており、より大きなコミュニティがあります。つまり、より多くのリソースとサポートが得られることを意味します。 testdouble.jsは、sinon.jsよりもシンプルで直感的なAPIを持っています。使いやすく理解できるように設計されているため、より合理化されたテスト方法を好む人には最適です。また、テストのスタンドインを乱用することを困難にすることにより、優れたテストの実践を奨励しています。
を使用してスパイを作成できます。この関数は、パラメーター、戻り値、例外など、作成されたすべての呼び出しを記録するSPYオブジェクトを返します。 testdouble.jsでは、
を使用してスパイを作成できます。この関数は、パラメーターを含むすべての呼び出しを記録するテストスタンドアロン関数を返します。 td.function()
を使用してスタブを作成できます。この関数は、スパイのように動作するスタブオブジェクトを返しますが、返品値の指定や例外のスローなど、その動作を定義することもできます。 testDouble.jsでは、
はい、sinon.jsとtestdouble.jsはどちらも非常にきれいに設計されており、他のテストフレームワークとうまく連携しています。 JavaScript対応のテストフレームワークで使用できます。 sinon.stub()
、td.when()
などのメソッドを使用して、スパイやスタブを検証できます。 TestDouble.jsでは、
testdouble.jsの代わりにsinon.jsを使用することの利点は何ですか?
sinon.jsの代わりにtestdouble.jsを使用することの利点は何ですか?
はい、sinon.jsとtestdouble.jsには、公式ウェブサイトに多くのドキュメントがあります。また、これらのライブラリからの詳細なコンテンツをカバーする多くのチュートリアル、ブログ投稿、オンラインコースもあります。
以上がJavaScriptテストツールの対決:sinon.js vs testdouble.jsの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。