国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
關(guān)鍵要點(diǎn)
本文中使用的術(shù)語
Sinon.js 和 testdouble.js 概述
更詳細(xì)地比較常見的測試任務(wù)
testdouble.js 沒有間諜
testdouble.js 需要更精確的輸入
testdouble.js 具有內(nèi)置 Promise 支持
testdouble.js 的回調(diào)支持更強(qiáng)大
testdouble.js 具有內(nèi)置模塊替換
testdouble.js 缺少 Sinon 的一些輔助函數(shù)
使用 testdouble.js 更容易清理測試後的內(nèi)容
優(yōu)缺點(diǎn)
按功能比較
總結(jié)和結(jié)論
那麼哪個適合我?
關(guān)於 JavaScript 測試工具的常見問題:Sinon.js 與 Testdouble.js
Sinon.js 和 Testdouble.js 的主要區(qū)別是什麼?
如何安裝 Sinon.js 和 Testdouble.js?
我可以同時使用 Sinon.js 和 Testdouble.js 嗎?
如何使用 Sinon.js 和 Testdouble.js 創(chuàng)建間諜?
如何使用 Sinon.js 和 Testdouble.js 創(chuàng)建存根?
如何使用 Sinon.js 和 Testdouble.js 驗(yàn)證間諜或存根?
使用 Sinon.js 而不是 Testdouble.js 的優(yōu)勢是什麼?
使用 Testdouble.js 而不是 Sinon.js 的優(yōu)勢是什麼?
我可以將 Sinon.js 和 Testdouble.js 與其他測試框架一起使用嗎?
有哪些資源可以學(xué)習(xí)更多關(guān)於 Sinon.js 和 Testdouble.js 的知識?
首頁 web前端 js教程 JavaScript測試工具攤牌:sinon.js vs testdouble.js

JavaScript測試工具攤牌:sinon.js vs testdouble.js

Feb 16, 2025 am 11:29 AM

JavaScript Testing Tool Showdown: Sinon.js vs testdouble.js

JavaScript Testing Tool Showdown: Sinon.js vs testdouble.js

在單元測試真實(shí)世界代碼時,許多情況使測試難以編寫。如何檢查是否調(diào)用了函數(shù)?如何測試 Ajax 調(diào)用?或者使用 setTimeout 的代碼?這時,您需要使用 測試替身 —— 替換代碼,使難以測試的內(nèi)容易於測試。

多年來,Sinon.js 一直是 JavaScript 測試中創(chuàng)建測試替身的實(shí)際標(biāo)準(zhǔn)。對於任何編寫測試的 JavaScript 開發(fā)人員來說,它都是必不可少的工具,因?yàn)闆]有它,為真實(shí)應(yīng)用程序編寫測試幾乎是不可能的。

最近,一個名為 testdouble.js 的新庫正在興起。它擁有與 Sinon.js 類似的功能集,只是這里和那裡有一些不同。

在本文中,我們將探討 Sinon.js 和 testdouble.js 提供的內(nèi)容,並比較它們各自的優(yōu)缺點(diǎn)。 Sinon.js 是否仍然是更好的選擇,或者挑戰(zhàn)者能否勝出?

注意:如果您不熟悉測試替身,建議您先閱讀我的 Sinon.js 教程。這將幫助您更好地理解我們將在此處討論的概念。

關(guān)鍵要點(diǎn)

  • 功能集和術(shù)語:Sinon.js 提供了一套傳統(tǒng)的測試替身,包括間諜、存根和模擬,這對於精通其他編程語言的人來說很熟悉,而testdouble.js 簡化了術(shù)語,並專注於更以JavaScript 為中心的詞彙,消除了傳統(tǒng)的間諜。
  • 易用性:Testdouble.js 擁有更簡單的API,初學(xué)者更容易掌握,而Sinon.js 提供了更詳細(xì)但更複雜的接口,熟悉其他語言中類似測試工具的用戶可能會更喜歡它。
  • 處理輸入的功能:Sinon.js 允許在存根和斷言中更靈活地使用輸入?yún)?shù),不一定需要完全匹配,這與 testdouble.js 除非明確配置,否則嚴(yán)格要求精確參數(shù)匹配形成對比。
  • 對Promise 和回調(diào)的支持:Testdouble.js 集成了對Promise 的內(nèi)置支持,並提供了強(qiáng)大的回調(diào)處理功能,與Sinon.js 相比,這可能更適合現(xiàn)代JavaScript 開發(fā),Sinon.js 需要額外的配置才能實(shí)現(xiàn)類似的功能。
  • 模塊替換功能:Testdouble.js 支持替換整個模塊,這有利於隔離測試模塊交互;此功能在 Sinon.js 中不可用,除非使用 proxyquire 或 rewire 等其他工具。
  • 清理和維護(hù):Testdouble.js 使用單個重置函數(shù)簡化了清理過程,從而減少了可能影響其他測試的剩餘測試替身的風(fēng)險,而Sinon.js 提供了多種清理方法,管理起來可能更麻煩。

本文中使用的術(shù)語

為了確保易於理解正在討論的內(nèi)容,以下是所用術(shù)語的快速概述。這些是 Sinon.js 的定義,在其他地方可能略有不同。

  • 測試替身是測試期間使用的函數(shù)的替代品。它可以指下面提到的三種類型中的任何一種。
  • 間諜是一種測試替身,它允許檢查效果而不影響目標(biāo)函數(shù)的行為。
  • 存根是一種測試替身,它用其他東西替換目標(biāo)函數(shù)的行為,例如返回值。
  • 模擬是一種與存根不同的方法。模擬包含內(nèi)置驗(yàn)證,可以替代單獨(dú)的斷言。

需要注意的是,testdouble.js 的目標(biāo)之一是減少這種術(shù)語之間的混淆。

Sinon.js 和 testdouble.js 概述

讓我們首先看看 Sinon.js 和 testdouble.js 在基本用法上的比較。

Sinon 有三種不同的測試替身概念:間諜、存根和模擬。其思想是,每種都代表不同的使用場景。這使得該庫對於來自其他語言或閱讀過使用相同術(shù)語的書籍(例如 xUnit 測試模式)的人來說更加熟悉。但另一方面,這三種概念也可能使 Sinon 在首次使用時 更難 理解。

這是一個 Sinon 用法的基本示例:

// 以下是查看函數(shù)調(diào)用的參數(shù)的方法:
var spy = sinon.spy(Math, 'abs');

Math.abs(-10);

console.log(spy.firstCall.args); // 輸出:[ -10 ]
spy.restore();

// 以下是控制函數(shù)執(zhí)行方式的方法:
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();

相反,testdouble.js 選擇了一個更簡單的 API。它不使用間諜或存根之類的概念,而是使用 JavaScript 開發(fā)人員更熟悉的語言,例如 td.function、td.objecttd.replace。這使得 testdouble 潛在地更容易上手,並且更適合某些任務(wù)。但另一方面,某些更高級的用途可能根本不可能實(shí)現(xiàn)(這有時是故意的)。

以下是 testdouble.js 的使用方法:

// 以下是查看函數(shù)調(diào)用的參數(shù)的方法:
var abs = td.replace(Math, 'abs');

Math.abs(-10);

var explanation = td.explain(abs);
console.log(explanation.calls[0].args); // 輸出:[ -10 ]

// 以下是控制函數(shù)執(zhí)行方式的方法:
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 使用一次調(diào)用重置所有測試替身,無需單獨(dú)清理
td.reset();

testdouble 使用的語言更簡單。我們“替換”函數(shù)而不是“存根”它。我們要求 testdouble “解釋”函數(shù)以從中獲取信息。除此之外,到目前為止,它與 Sinon 相當(dāng)相似。

這也擴(kuò)展到創(chuàng)建“匿名”測試替身:

var x = sinon.stub();

var x = td.function();

Sinon 的間諜和存根具有提供有關(guān)它們的更多信息的屬性。例如,Sinon 提供了 stub.callCountstub.args 等屬性。在 testdouble 的情況下,我們從 td.explain 獲取此信息:

// 我們也可以為測試替身命名
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
}
*/

較大的區(qū)別之一與設(shè)置存根和驗(yàn)證的方式有關(guān)。使用 Sinon,您可以在存根之後鏈接命令,並使用斷言來驗(yàn)證結(jié)果。 testdouble.js 只需向您展示您希望如何調(diào)用函數(shù)——或者如何“排練”函數(shù)調(diào)用。

var x = sinon.stub();
x.withArgs('hello', 'world').returns(true);

var y = sinon.stub();
sinon.assert.calledWith(y, 'foo', 'bar');

var x = td.function();
td.when(x('hello', 'world')).thenReturn(true);

var y = td.function();
td.verify(y('foo', 'bar'));

這使得 testdouble 的 API 更易於理解,因?yàn)槟恍枰揽梢栽诤螘r鏈接哪些操作。

更詳細(xì)地比較常見的測試任務(wù)

在高層次上,這兩個庫都相當(dāng)相似。但是您可能需要在實(shí)際項(xiàng)目中執(zhí)行的常見測試任務(wù)呢?讓我們看看一些差異開始顯現(xiàn)的情況。

testdouble.js 沒有間諜

首先要注意的是,testdouble.js 沒有“間諜”的概念。雖然 Sinon.js 允許我們替換函數(shù)調(diào)用以便從中獲取信息,同時保留函數(shù)的默認(rèn)行為,但這在 testdouble.js 中根本不可能。當(dāng)您使用 testdouble 替換函數(shù)時,它總是會丟失其默認(rèn)行為。

但這不一定是問題。間諜最常見的用法是使用它們來驗(yàn)證是否調(diào)用了回調(diào),這很容易使用 td.function 來完成:

var spy = sinon.spy();

myAsyncFunction(spy);

sinon.assert.calledOnce(spy);

var spy = td.function();

myAsyncFunction(spy);

td.verify(spy());

雖然不是什麼大問題,但仍然需要注意這兩個庫之間的這種差異,否則如果您期望能夠以某種更具體的方式使用 testdouble.js 中的間諜,您可能會感到驚訝。

testdouble.js 需要更精確的輸入

您會遇到的第二個區(qū)別是 testdouble 對輸入更嚴(yán)格。

Sinon 的存根和斷言都允許您對提供的參數(shù)不精確。這最容易通過示例來說明:

var stub = sinon.stub();
stub.withArgs('hello').returns('foo');

console.log(stub('hello', 'world')); // 輸出:'foo'

sinon.assert.calledWith(stub, 'hello'); // 沒有錯誤

// 以下是查看函數(shù)調(diào)用的參數(shù)的方法:
var spy = sinon.spy(Math, 'abs');

Math.abs(-10);

console.log(spy.firstCall.args); // 輸出:[ -10 ]
spy.restore();

// 以下是控制函數(shù)執(zhí)行方式的方法:
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();

默認(rèn)情況下,Sinon 不關(guān)心向函數(shù)提供了多少額外參數(shù)。雖然它提供了諸如 sinon.assert.calledWithExactly 之類的函數(shù),但在文檔中並不建議將其作為默認(rèn)值。像 stub.withArgs 這樣的函數(shù)也沒有“exactly”變體。

另一方面,testdouble.js 默認(rèn)情況下要求指定精確的參數(shù)。這是設(shè)計(jì)使然。其思想是,如果向函數(shù)提供了一些在測試中未指定的其他參數(shù),則這可能是一個錯誤,並且應(yīng)該使測試失敗。

可以在 testdouble.js 中允許指定任意參數(shù),但這並不是默認(rèn)值:

// 以下是查看函數(shù)調(diào)用的參數(shù)的方法:
var abs = td.replace(Math, 'abs');

Math.abs(-10);

var explanation = td.explain(abs);
console.log(explanation.calls[0].args); // 輸出:[ -10 ]

// 以下是控制函數(shù)執(zhí)行方式的方法:
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 使用一次調(diào)用重置所有測試替身,無需單獨(dú)清理
td.reset();

使用 ignoreExtraArgs: true,行為類似於 Sinon.js。

testdouble.js 具有內(nèi)置 Promise 支持

雖然使用 Sinon.js 的 Promise 並不復(fù)雜,但 testdouble.js 具有返回和拒絕 Promise 的內(nèi)置方法。

var x = sinon.stub();

var x = td.function();

注意:可以使用 sinon-as-promised 在 Sinon 1.x 中包含類似的便捷函數(shù)。 Sinon 2.0 和更新版本以 stub.resolvesstub.rejects 的形式包含 Promise 支持。

testdouble.js 的回調(diào)支持更強(qiáng)大

Sinon 和 testdouble 都提供了一種簡單的方法來讓存根函數(shù)調(diào)用回調(diào)。但是,它們在工作方式上有一些差異。

Sinon 使用 stub.yields 來讓存根調(diào)用它作為參數(shù)接收的 第一個函數(shù)

// 我們也可以為測試替身命名
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
}
*/

testdouble.js 默認(rèn)使用 Node 樣式模式,其中回調(diào)被假定為 最後一個 參數(shù)。在排練調(diào)用時,您也不必指定它:

var x = sinon.stub();
x.withArgs('hello', 'world').returns(true);

var y = sinon.stub();
sinon.assert.calledWith(y, 'foo', 'bar');

使 testdouble 的回調(diào)支持更強(qiáng)大的原因是您可以輕鬆定義具有多個回調(diào)或回調(diào)順序不同的場景的行為。

假設(shè)我們想調(diào)用 callback1……

var x = td.function();
td.when(x('hello', 'world')).thenReturn(true);

var y = td.function();
td.verify(y('foo', 'bar'));

請注意,我們將 td.callback 作為參數(shù)傳遞給 td.when 中的函數(shù)。這告訴 testdouble 我們希望使用哪個參數(shù)作為回調(diào)。

使用 Sinon,也可以更改行為:

var spy = sinon.spy();

myAsyncFunction(spy);

sinon.assert.calledOnce(spy);

在這種情況下,我們使用 callsArgWith 而不是 yields。我們必須提供調(diào)用的特定索引才能使其工作,這可能有點(diǎn)麻煩,尤其是在具有許多參數(shù)的函數(shù)上。

如果我們想使用某些值調(diào)用 兩個 回調(diào)呢?

var spy = td.function();

myAsyncFunction(spy);

td.verify(spy());

使用 Sinon,這根本不可能。您可以鏈接對 callsArgWith 的多次調(diào)用,但它只會調(diào)用其中一個。

testdouble.js 具有內(nèi)置模塊替換

除了能夠使用 td.replace 替換函數(shù)之外,testdouble 還允許您替換整個模塊。

這主要在您有一個直接導(dǎo)出需要替換的函數(shù)的模塊的情況下有用:

var stub = sinon.stub();
stub.withArgs('hello').returns('foo');

console.log(stub('hello', 'world')); // 輸出:'foo'

sinon.assert.calledWith(stub, 'hello'); // 沒有錯誤

如果我們想用 testdouble 替換它,我們可以使用 td.replace('path/to/file'),例如……

// 以下是查看函數(shù)調(diào)用的參數(shù)的方法:
var spy = sinon.spy(Math, 'abs');

Math.abs(-10);

console.log(spy.firstCall.args); // 輸出:[ -10 ]
spy.restore();

// 以下是控制函數(shù)執(zhí)行方式的方法:
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();

雖然 Sinon.js 可以替換某個對象的成員函數(shù),但它不能像這樣替換模塊。在使用 Sinon 時要執(zhí)行此操作,您需要使用另一個模塊,例如 proxyquire 或 rewire。

// 以下是查看函數(shù)調(diào)用的參數(shù)的方法:
var abs = td.replace(Math, 'abs');

Math.abs(-10);

var explanation = td.explain(abs);
console.log(explanation.calls[0].args); // 輸出:[ -10 ]

// 以下是控制函數(shù)執(zhí)行方式的方法:
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 使用一次調(diào)用重置所有測試替身,無需單獨(dú)清理
td.reset();

關(guān)於模塊替換需要注意的另一件事是 testdouble.js 會自動替換整個模塊。如果它像這裡的示例一樣是函數(shù)導(dǎo)出,它會替換該函數(shù)。如果它是一個包含多個函數(shù)的對象,它會替換所有這些函數(shù)。構(gòu)造函數(shù)和 ES6 類也受支持。 proxyquire 和 rewire 都要求您單獨(dú)指定要替換的內(nèi)容和方式。

testdouble.js 缺少 Sinon 的一些輔助函數(shù)

如果您使用 Sinon 的模擬計(jì)時器、模擬 XMLHttpRequest 或模擬服務(wù)器,您會注意到它們在 testdouble 中不存在。

模擬計(jì)時器可以作為插件使用,但 XMLHttpRequests 和 Ajax 功能需要以不同的方式處理。

一個簡單的解決方案是替換您正在使用的 Ajax 函數(shù),例如 $.post

var x = sinon.stub();

使用 testdouble.js 更容易清理測試後的內(nèi)容

對於 Sinon.js 的初學(xué)者來說,一個常見的絆腳石往往是清理間諜和存根。 Sinon 提供了 三種 不同的方法來做到這一點(diǎn),這並沒有什麼幫助。

var x = td.function();

或:

// 我們也可以為測試替身命名
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
}
*/

或:

var x = sinon.stub();
x.withArgs('hello', 'world').returns(true);

var y = sinon.stub();
sinon.assert.calledWith(y, 'foo', 'bar');

通常情況下,建議使用 sandbox 和 sinon.test 方法,否則很容易意外地留下存根或間諜,這可能會導(dǎo)致其他測試出現(xiàn)問題。這可能會導(dǎo)致難以追蹤的級聯(lián)故障。

testdouble.js 只提供了一種清理測試替身的方法:td.reset()。推薦的方法是在 afterEach 鉤子中調(diào)用它:

var x = td.function();
td.when(x('hello', 'world')).thenReturn(true);

var y = td.function();
td.verify(y('foo', 'bar'));

這極大地簡化了測試替身的設(shè)置和測試後的清理,降低了難以追蹤的錯誤的可能性。

優(yōu)缺點(diǎn)

我們現(xiàn)在已經(jīng)了解了這兩個庫的功能。它們都提供了一套相當(dāng)類似的功能集,但它們彼此的設(shè)計(jì)理念有所不同。我們能否將其分解為優(yōu)缺點(diǎn)?

讓我們首先談?wù)?Sinon.js。它提供了一些比 testdouble.js 更多的附加功能,並且它的一些方面更易於配置。這為它在更特殊的測試場景中提供了一些更高的靈活性。 Sinon.js 還使用更熟悉其他語言的人的語言——間諜、存根和模擬等概念存在於不同的庫中,並且也在測試相關(guān)的書籍中討論過。

缺點(diǎn)是增加了複雜性。雖然它的靈活性允許專家做更多的事情,但這意味著某些任務(wù)比在 testdouble.js 中更複雜。對於那些剛接觸測試替身概念的人來說,它也可能具有更陡峭的學(xué)習(xí)曲線。事實(shí)上,即使像我這樣非常熟悉它的人也可能難以詳細(xì)說明 sinon.stubsinon.mock 之間的某些區(qū)別!

testdouble.js 選擇了一個更簡單的接口。它的大部分內(nèi)容都相當(dāng)簡單易用,並且感覺更適合 JavaScript,而 Sinon.js 有時感覺像是為其他語言設(shè)計(jì)的。由於這一點(diǎn)及其一些設(shè)計(jì)原則,它對於初學(xué)者來說更容易上手,即使是經(jīng)驗(yàn)豐富的測試人員也會發(fā)現(xiàn)許多任務(wù)更容易完成。例如,testdouble 使用相同的 API 來設(shè)置測試替身和驗(yàn)證結(jié)果。由於其更簡單的清理機(jī)制,它也可能更不容易出錯。

testdouble 最大的問題是由它的一些設(shè)計(jì)原則造成的。例如,完全缺乏間諜可能會使某些更喜歡使用間諜而不是存根的人無法使用它。這在很大程度上是一個意見問題,您可能根本不會發(fā)現(xiàn)問題。除此之外,儘管 testdouble.js 是一個更新的庫,但它正在為 Sinon.js 提供一些嚴(yán)重的競爭。

按功能比較

以下是按功能的比較:

功能 Sinon.js testdouble.js
間諜
存根
延遲存根結(jié)果
模擬 1
Promise 支持 是(在 2.0 中)
時間輔助函數(shù) 是(通過插件)
Ajax 輔助函數(shù) 否(改為替換函數(shù))
模塊替換
內(nèi)置斷言
匹配器
自定義匹配器
參數(shù)捕獲器 2
代理測試替身
  1. testdouble.js 從技術(shù)上講 沒有 Sinon.js 中那樣的模擬。但是,由於 Sinon 中的模擬本質(zhì)上是包含存根和驗(yàn)證的對象,因此可以通過使用 td.replace(someObject) 來實(shí)現(xiàn)類似的效果。
  2. 可以通過使用 stub.yield(不要與 stub.yields 混淆)來實(shí)現(xiàn)與參數(shù)捕獲器類似的效果。

總結(jié)和結(jié)論

Sinon.js 和 testdouble.js 都提供了一套相當(dāng)類似的功能。在這方面,兩者都不明顯優(yōu)越。

兩者之間最大的區(qū)別在於它們的 API。 Sinon.js 可能稍微冗長一些,同時提供了許多關(guān)於如何做事情的選項(xiàng)。這可能是它的優(yōu)點(diǎn)和缺點(diǎn)。 testdouble.js 具有更精簡的 API,這使其更容易學(xué)習(xí)和使用,但由於其更武斷的設(shè)計(jì),有些人可能會發(fā)現(xiàn)它有問題。

那麼哪個適合我?

您是否同意 testdouble 的設(shè)計(jì)原則?如果是,那麼沒有理由不使用它。我在許多項(xiàng)目中都使用過 Sinon.js,我可以肯定地說 testdouble.js 至少完成了我在 Sinon.js 中完成的 95% 的工作,其餘 5% 可能可以通過一些簡單的解決方法來完成。

如果您發(fā)現(xiàn) Sinon.js 難以使用,或者正在尋找更“JavaScript 式”的測試替身方法,那麼 testdouble.js 也可能適合您。即使像我這樣花了很多時間學(xué)習(xí)使用 Sinon 的人,我也傾向於建議嘗試 testdouble.js 並看看您是否喜歡它。

但是,testdouble.js 的某些方面可能會讓那些了解 Sinon.js 或其他經(jīng)驗(yàn)豐富的測試人員頭疼。例如,完全缺乏間諜可能是決定性因素。對於專家和那些想要最大靈活性的用戶來說,Sinon.js 仍然是一個不錯的選擇。

如果您想了解更多關(guān)於如何在實(shí)踐中使用測試替身的信息,請查看我的免費(fèi) Sinon.js 實(shí)戰(zhàn)指南。雖然它使用 Sinon.js,但您也可以將相同的技術(shù)和最佳實(shí)踐應(yīng)用於 testdouble.js。

有問題?評論?您是否已經(jīng)在使用 testdouble.js 了?閱讀本文後,您是否會考慮嘗試一下?請?jiān)谙旅娴脑u論中告訴我。

本文由 James Wright、Joan Yin、Christian Johansen 和 Justin Searls 共同評審。感謝所有 SitePoint 的同行評審者,使 SitePoint 內(nèi)容達(dá)到最佳狀態(tài)!

關(guān)於 JavaScript 測試工具的常見問題:Sinon.js 與 Testdouble.js

Sinon.js 和 Testdouble.js 的主要區(qū)別是什麼?

Sinon.js 和 Testdouble.js 都是流行的 JavaScript 測試庫,但它們有一些關(guān)鍵區(qū)別。 Sinon.js 以其豐富的功能集而聞名,包括間諜、存根和模擬,以及用於模擬計(jì)時器和 XHR 的實(shí)用程序。它是一個多功能工具,可以與任何測試框架結(jié)合使用。另一方面,Testdouble.js 是一個極簡的庫,專注於為測試替身提供簡單直觀的 API,測試替身是待測系統(tǒng)部分的替代品。它不包括用於模擬計(jì)時器或 XHR 的實(shí)用程序,但它設(shè)計(jì)易於使用和理解,因此對於那些更喜歡更精簡的測試方法的人來說是一個不錯的選擇。

如何安裝 Sinon.js 和 Testdouble.js?

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 嗎?

是的,可以在同一個項(xiàng)目中同時使用 Sinon.js 和 Testdouble.js。它們都設(shè)計(jì)得非常簡潔,並且可以很好地與其他庫一起工作。但是,請記住它們具有重疊的功能,因此同時使用它們可能會導(dǎo)致混淆。通常建議根據(jù)您的具體需求和偏好選擇其中一個。

如何使用 Sinon.js 和 Testdouble.js 創(chuàng)建間諜?

在 Sinon.js 中,您可以使用 sinon.spy() 創(chuàng)建間諜。此函數(shù)返回一個間諜對象,該對象記錄對其進(jìn)行的所有調(diào)用,包括參數(shù)、返回值和異常。在 Testdouble.js 中,您可以使用 td.function() 創(chuàng)建間諜。此函數(shù)返回一個記錄所有調(diào)用的測試替身函數(shù),包括參數(shù)。

如何使用 Sinon.js 和 Testdouble.js 創(chuàng)建存根?

在 Sinon.js 中,您可以使用 sinon.stub() 創(chuàng)建存根。此函數(shù)返回一個存根對象,其行為類似於間諜,但它還允許您定義其行為,例如指定返回值或拋出異常。在 Testdouble.js 中,您可以使用 td.when() 創(chuàng)建存根。此函數(shù)允許您在使用特定參數(shù)調(diào)用測試替身時定義其行為。

如何使用 Sinon.js 和 Testdouble.js 驗(yàn)證間諜或存根?

在 Sinon.js 中,您可以使用 spy.called、spy.calledWith()spy.returned() 等方法來驗(yàn)證間諜或存根。在 Testdouble.js 中,您可以使用 td.verify() 來斷言測試替身是否以某種方式被調(diào)用。

使用 Sinon.js 而不是 Testdouble.js 的優(yōu)勢是什麼?

與 Testdouble.js 相比,Sinon.js 具有更全面的功能集。它包括用於模擬計(jì)時器和 XHR 的實(shí)用程序,這對於測試某些類型的代碼非常有用。它也更廣泛地使用,並且擁有更大的社區(qū),這意味著可以獲得更多資源和支持。

使用 Testdouble.js 而不是 Sinon.js 的優(yōu)勢是什麼?

與 Sinon.js 相比,Testdouble.js 具有更簡單直觀的 API。它設(shè)計(jì)易於使用和理解,因此對於那些更喜歡更精簡的測試方法的人來說是一個不錯的選擇。它還通過使濫用測試替身變得困難來鼓勵良好的測試實(shí)踐。

我可以將 Sinon.js 和 Testdouble.js 與其他測試框架一起使用嗎?

是的,Sinon.js 和 Testdouble.js 都設(shè)計(jì)得非常簡潔,並且可以很好地與其他測試框架一起工作。它們可以與任何支持 JavaScript 的測試框架一起使用。

有哪些資源可以學(xué)習(xí)更多關(guān)於 Sinon.js 和 Testdouble.js 的知識?

是的,Sinon.js 和 Testdouble.js 在其官方網(wǎng)站上都有大量的文檔。還有許多教程、博客文章和在線課程涵蓋了這些庫的深入內(nèi)容。

以上是JavaScript測試工具攤牌:sinon.js vs testdouble.js的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點(diǎn)能有效避免常見錯誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應(yīng)用戶操作的時機(jī)和方式。

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

如何減少JavaScript應(yīng)用程序的有效載荷大??? 如何減少JavaScript應(yīng)用程序的有效載荷大??? Jun 26, 2025 am 12:54 AM

如果JavaScript應(yīng)用加載慢、性能差,問題往往出在payload太大,解決方法包括:1.使用代碼拆分(CodeSplitting),通過React.lazy()或構(gòu)建工具將大bundle拆分為多個小文件,按需加載以減少首次下載量;2.移除未使用的代碼(TreeShaking),利用ES6模塊機(jī)制清除“死代碼”,確保引入的庫支持該特性;3.壓縮和合併資源文件,啟用Gzip/Brotli和Terser壓縮JS,合理合併文件並優(yōu)化靜態(tài)資源;4.替換重型依賴,選用輕量級庫如day.js、fetch

See all articles