首頁 >web前端 >js教程 >Sinon教程:使用模擬,間諜和存根的JavaScript測試

Sinon教程:使用模擬,間諜和存根的JavaScript測試

Joseph Gordon-Levitt
Joseph Gordon-Levitt原創
2025-02-18 10:13:13688瀏覽

Sinon Tutorial: JavaScript Testing with Mocks, Spies & Stubs

本文由 Mark Brown 和 Marc Towler 審核。感謝所有 SitePoint 的同行評審員,使 SitePoint 的內容達到最佳狀態!

編寫單元測試時,最大的障礙之一是如何處理非平凡的代碼。

在實際項目中,代碼經常執行各種使測試變得困難的操作。 Ajax 請求、計時器、日期、訪問其他瀏覽器功能……或者如果您使用的是 Node.js,數據庫總是很有趣,網絡或文件訪問也是如此。

所有這些都很難測試,因為您無法在代碼中控制它們。如果您使用的是 Ajax,則需要一個服務器來響應請求,以便使您的測試通過。如果您使用 setTimeout,您的測試將不得不等待。對於數據庫或網絡,情況也是一樣——您需要一個包含正確數據的數據庫,或一個網絡服務器。

現實生活不像許多測試教程看起來那樣容易。但您知道有解決方案嗎?

通過使用 Sinon,我們可以使測試非平凡的代碼變得微不足道!

讓我們看看它是如何工作的。

關鍵要點

  • Sinon 簡化測試:Sinon.js 對於簡化涉及復雜操作(如 Ajax 調用、計時器和數據庫交互)的 JavaScript 代碼的測試至關重要,因為它允許用模擬、間諜和存根替換這些部分。
  • 三種類型的測試替身:Sinon 將測試替身分為間諜(收集有關函數調用的信息);存根(可以替換函數以強制執行特定行為);以及模擬(非常適合替換和斷言整個對象的行為)。
  • 實用案例:Sinon 在單元測試場景中特別有用,在這些場景中,外部依賴項會使測試複雜化或減慢測試速度,例如外部 API 調用或基於時間的函數。
  • 集成和設置:Sinon 可以輕鬆集成到 Node.js 和基於瀏覽器的測試環境中,增強其在各種 JavaScript 應用程序中的多功能性和易用性。
  • 增強的斷言:Sinon 提供增強的斷言方法,這些方法會生成更清晰的錯誤消息,從而改進測試失敗期間的調試過程。
  • 最佳實踐:使用 sinon.test() 包裝測試用例可確保正確清理測試替身,防止在其他測試中產生副作用,並減少測試套件中潛在的錯誤。

是什麼使 Sinon 如此重要和有用?

簡而言之,Sinon 允許您將測試的困難部分替換為使測試變得簡單的部分。

在測試一段代碼時,您不希望它受到測試外部任何因素的影響。如果某些外部因素影響測試,則測試會變得更加複雜,並且可能會隨機失敗。

如果您想測試進行 Ajax 調用的代碼,該如何操作?您需要運行一個服務器並確保它提供測試所需的精確響應。設置起來很複雜,並且使編寫和運行單元測試變得困難。

如果您的代碼依賴於時間怎麼辦?假設它等待一秒鐘後再執行某些操作。現在怎麼辦?您可以在測試中使用 setTimeout 來等待一秒鐘,但這會使測試變慢。想像一下,如果間隔更長,例如五分鐘。我猜您可能不想每次運行測試時都等待五分鐘。

通過使用 Sinon,我們可以解決這兩個問題(以及許多其他問題),並消除複雜性。

Sinon 如何工作?

Sinon 通過允許您輕鬆創建所謂的 測試替身 來幫助消除測試中的複雜性。

顧名思義,測試替身是測試中使用的代碼片段的替代品。回顧 Ajax 示例,我們不會設置服務器,而是會將 Ajax 調用替換為測試替身。對於時間示例,我們將使用測試替身來允許我們“向前移動時間”。

這聽起來可能有點奇怪,但基本概念很簡單。因為 JavaScript 非常動態,所以我們可以獲取任何函數並將其替換為其他內容。測試替身只是將這個想法更進一步。使用 Sinon,我們可以用測試替身替換任何 JavaScript 函數,然後可以對其進行配置以執行各種操作,使測試複雜的事情變得簡單。

Sinon 將測試替身分為三種類型:

  • 間諜,提供有關函數調用的信息,而不會影響其行為
  • 存根,就像間諜一樣,但完全替換了函數。這使得可以使存根函數執行任何您喜歡的事情——拋出異常、返回特定值等
  • 模擬,通過組合間諜和存根,使替換整個對象更容易

此外,Sinon 還提供了一些其他幫助程序,儘管這些幫助程序不在本文的討論範圍之內:

  • 假計時器,可用於向前移動時間,例如觸發 setTimeout
  • 假 XMLHttpRequest 和服務器,可用於偽造 Ajax 請求和響應

憑藉這些功能,Sinon 允許您解決外部依賴項在測試中導致的所有難題。如果您學習有效使用 Sinon 的技巧,則不需要任何其他工具。

安裝 Sinon

首先,我們需要安裝 Sinon。

對於 Node.js 測試:

  1. 使用 npm install sinon 通過 npm 安裝 Sinon
  2. 使用 var sinon = require('sinon'); 在您的測試中引入 Sinon

對於基於瀏覽器的測試:

  1. 您可以使用 npm install sinon 通過 npm 安裝 Sinon,使用 CDN 或從 Sinon 的網站下載它
  2. 在您的測試運行程序頁面中包含 sinon.js。

入門

Sinon 具有許多功能,但其中許多功能都是建立在其自身之上的。您了解一部分,就已經了解了下一部分。一旦您了解了基礎知識並了解了每個不同部分的作用,這就會使 Sinon 易於使用。

當我們的代碼調用給我們帶來麻煩的函數時,我們通常需要 Sinon。

對於 Ajax,它可能是 $.get 或 XMLHttpRequest。對於時間,該函數可能是 setTimeout。對於數據庫,它可能是 mongodb.findOne。

為了更容易討論此函數,我將其稱為 依賴項。我們正在測試的函數 依賴 於另一個函數的結果。

我們可以說,Sinon 的基本使用模式是用測試替身替換有問題的依賴項。

  • 在測試 Ajax 時,我們將 XMLHttpRequest 替換為一個模擬 Ajax 請求的測試替身
  • 在測試時間時,我們將 setTimeout 替換為一個假計時器
  • 在測試數據庫訪問時,我們可以將 mongodb.findOne 替換為一個立即返回一些假數據的測試替身

讓我們看看它在實踐中是如何工作的。

間諜

間諜是 Sinon 最簡單的部分,其他功能建立在其之上。

間諜的主要用途是收集有關函數調用的信息。您還可以使用它們來幫助驗證某些事情,例如是否調用了函數。

<code class="language-javascript">var spy = sinon.spy();

//我们可以像函数一样调用间谍
spy('Hello', 'World');

//现在我们可以获取有关调用的信息
console.log(spy.firstCall.args); //输出:['Hello', 'World']
</code>

函數 sinon.spy 返回一個 Spy 對象,可以像函數一樣調用它,但還包含有關對其進行的任何調用的信息的屬性。在上面的示例中,firstCall 屬性包含有關第一次調用的信息,例如 firstCall.args,它是傳遞的參數列表。

儘管您可以通過不帶參數地調用 sinon.spy 來創建匿名間諜,但更常見的模式是用間諜替換另一個函數。

<code class="language-javascript">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();
</code>

用間諜替換另一個函數的工作方式與前面的示例類似,但有一個重要的區別:完成使用間諜後,務必記住恢復原始函數,如上面示例的最後一行所示。如果沒有這個,您的測試可能會行為異常。

間諜有很多不同的屬性,這些屬性提供了關於它們如何使用的不同信息。 Sinon 的間諜文檔包含所有可用選項的完整列表。

在實踐中,您可能不會經常使用間諜。您更有可能需要一個存根,但間諜可能很方便,例如驗證是否調用了回調:

<code class="language-javascript">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);
  });
});
</code>

在這個例子中,我使用 Mocha 作為測試框架,使用 Chai 作為斷言庫。如果您想了解更多關於這兩個的信息,請參考我之前的文章:使用 Mocha 和 Chai 對您的 JavaScript 進行單元測試。

Sinon 的斷言

在我們繼續討論存根之前,讓我們快速繞道一下,看看 Sinon 的斷言。

在大多數使用間諜(和存根)的測試情況下,您需要某種方法來驗證測試的結果。

我們可以使用任何類型的斷言來驗證結果。在前面關於回調的示例中,我們使用了 Chai 的 assert 函數,它確保該值是真值。

<code class="language-javascript">var spy = sinon.spy();

//我们可以像函数一样调用间谍
spy('Hello', 'World');

//现在我们可以获取有关调用的信息
console.log(spy.firstCall.args); //输出:['Hello', 'World']
</code>

這樣做的缺點是失敗時的錯誤消息不清楚。您只會收到“false 不是 true”或類似的提示。正如您可能想像的那樣,這在找出問題所在方面幫助不大,您需要查看測試的源代碼才能弄清楚。不好玩。

為了解決這個問題,我們可以將自定義錯誤消息包含到斷言中。

<code class="language-javascript">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();
</code>

但是,當我們可以使用 Sinon 自身的斷言 時,為什麼要費心呢?

<code class="language-javascript">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);
  });
});
</code>

像這樣使用 Sinon 的斷言可以立即提供更好的錯誤消息。當您需要驗證更複雜的條件(例如函數的參數)時,這會非常有用。

以下是 Sinon 提供的其他一些有用斷言的示例:

  • sinon.assert.calledWith 可用於驗證是否使用特定參數調用了函數(這可能是我最常用的一個)
  • sinon.assert.callOrder 可以驗證函數是否按特定順序調用

與間諜一樣,Sinon 的斷言文檔包含所有可用的選項。如果您喜歡使用 Chai,還有一個 sinon-chai 插件可用,它允許您通過 Chai 的 expect 或 should 接口使用 Sinon 斷言。

存根

存根是首選的測試替身,因為它們靈活且方便。它們具有間諜的所有功能,但它們不僅僅是監視函數的作用,存根完全替換了它。換句話說,使用間諜時,原始函數仍然運行,但使用存根時,它不會運行。

這使得存根非常適合許多任務,例如:

  • 替換使測試編寫緩慢且困難的 Ajax 或其他外部調用
  • 根據函數輸出觸發不同的代碼路徑
  • 測試異常情況,例如拋出異常時會發生什麼?

我們可以創建存根的方式與間諜類似……

<code class="language-javascript">assert(callback.calledOnce);
</code>

我們可以像間諜一樣創建匿名存根,但是當您使用存根替換現有函數時,存根會變得非常有用。

例如,如果我們有一些使用 jQuery 的 Ajax 功能的代碼,則測試它很困難。代碼會向我們配置的任何服務器發送請求,因此我們需要使它可用,或者向代碼添加一個特殊情況,以便不在測試環境中執行此操作——這是一個很大的禁忌。您幾乎不應該在代碼中包含特定於測試的情況。

與其求助於不良做法,我們可以使用 Sinon 並將 Ajax 功能替換為存根。這使得測試它變得微不足道。

這是一個我們將測試的示例函數。它將對像作為參數,並通過 Ajax 將其發送到預定義的 URL。

<code class="language-javascript">var spy = sinon.spy();

//我们可以像函数一样调用间谍
spy('Hello', 'World');

//现在我们可以获取有关调用的信息
console.log(spy.firstCall.args); //输出:['Hello', 'World']
</code>

通常,由於 Ajax 調用和預定義的 URL,測試這將很困難,但如果我們使用存根,它就會變得很容易。

假設我們要確保傳遞給 saveUser 的回調函數在請求完成後正確調用。

<code class="language-javascript">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();
</code>

在這裡,我們用存根替換 Ajax 函數。這意味著請求永遠不會發送,我們不需要服務器或任何東西——我們完全控制測試代碼中發生的事情!

因為我們想確保我們傳遞給 saveUser 的回調被調用,所以我們將指示存根 yield。這意味著存根會自動調用作為參數傳遞給它的第一個函數。這模擬了 $.post 的行為,它會在請求完成後調用回調。

除了存根之外,我們還在此測試中創建了一個間諜。我們可以使用普通函數作為回調,但使用間諜可以很容易地使用 Sinon 的 sinon.assert.calledOnce 斷言來驗證測試的結果。

在大多數情況下,當您需要存根時,您可以遵循相同的基本模式:

  • 找到有問題的函數,例如 $.post
  • 查看它的工作方式,以便您可以在測試中模擬它
  • 創建一個存根
  • 將存根設置為在測試中具有所需的行為

存根不需要模擬每種行為。測試所需的唯一行為是必要的,其他任何東西都可以省略。

存根的另一個常見用法是驗證是否使用特定參數集調用了函數。

例如,對於我們的 Ajax 功能,我們要確保發送正確的值。因此,我們可以有類似以下內容:

<code class="language-javascript">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);
  });
});
</code>

同樣,我們為 $.post() 創建了一個存根,但這次我們沒有將其設置為 yield。此測試不關心回調,因此讓它 yield 是不必要的。

我們設置了一些變量來包含預期數據——URL 和參數。設置這樣的變量是一個好習慣,因為它可以讓我們一目了然地看到測試的要求。它還可以幫助我們設置用戶變量而無需重複值。

這次我們使用了 sinon.assert.calledWith() 斷言。我們將存根作為它的第一個參數傳遞,因為這次我們要驗證存根是否使用正確的參數調用。

還有另一種在 Sinon 中測試 Ajax 請求的方法。這是通過使用 Sinon 的假 XMLHttpRequest 功能來實現的。我們不會在這裡詳細介紹它,但如果您想了解它的工作原理,請參閱我關於使用 Sinon 的假 XMLHttpRequest 進行 Ajax 測試的文章。

模擬

模擬是一種與存根不同的方法。如果您聽說過“模擬對象”這個術語,這就是同樣的意思——Sinon 的模擬可以用來替換整個對象並改變它們的行為,類似於存根函數。

如果您需要從單個對象存根多個函數,它們主要是有用的。如果您只需要替換單個函數,則存根更容易使用。

使用模擬時,您應該小心!由於它們的強大功能,很容易使您的測試過於具體——測試過多且過於具體的事情——這可能會使您的測試無意中變得脆弱。

與間諜和存根不同,模擬具有內置斷言。您可以預先定義預期結果,方法是告訴模擬對象需要發生什麼,然後在測試結束時調用驗證函數。

假設我們使用 store.js 將內容保存到 localStorage,並且我們想測試與之相關的函數。我們可以使用模擬來幫助測試它,如下所示:

<code class="language-javascript">var spy = sinon.spy();

//我们可以像函数一样调用间谍
spy('Hello', 'World');

//现在我们可以获取有关调用的信息
console.log(spy.firstCall.args); //输出:['Hello', 'World']
</code>

使用模擬時,我們使用流暢的調用樣式定義預期的調用及其結果,如上所示。這與使用斷言驗證測試結果相同,只是我們預先定義了它們,並且為了驗證它們,我們在測試結束時調用 storeMock.verify()。

在 Sinon 的模擬對象術語中,調用 mock.expects('something') 會創建一個 期望。也就是說,方法 mock.something() 預計會被調用。每個期望除了模擬特定功能外,還支持與間諜和存根相同的函數。

您可能會發現,使用存根通常比使用模擬更容易——這完全沒問題。應該謹慎使用模擬。

有關模擬特定函數的完整列表,請查看 Sinon 的模擬文檔。

重要的最佳實踐:使用 sinon.test()

Sinon 有一個重要的最佳實踐,在使用間諜、存根或模擬時應記住。

如果您用測試替身替換現有函數,請使用 sinon.test()。

在前面的示例中,我們使用 stub.restore() 或 mock.restore() 來清理使用它們後的內容。這是必要的,因為否則測試替身將保留在原處,並且可能會對其他測試產生負面影響或導致錯誤。

但是直接使用 restore() 函數是有問題的。被測試的函數可能會導致錯誤,並在調用 restore() 之前結束測試函數!

我們有兩種方法可以解決這個問題:我們可以將整個內容包裝在一個 try catch 塊中。這允許我們將 restore() 調用放在 finally 塊中,確保無論發生什麼都會運行它。

或者,更好的方法是使用 sinon.test() 包裝測試函數

<code class="language-javascript">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();
</code>

在上面的示例中,請注意 it() 的第二個參數包裝在 sinon.test() 中。需要注意的第二件事是,我們使用 this.stub() 而不是 sinon.stub()。

使用sinon.test() 包裝測試允許我們使用Sinon 的沙箱 功能,允許我們通過this.spy()、this.stub() 和this.mock() 創建間諜、存根和模擬。使用沙箱創建的任何測試替身都會 自動 清理。

請注意,我們上面的示例代碼沒有 stub.restore()——由於測試被沙箱化,因此它是不必要的。

如果盡可能使用 sinon.test(),您可以避免由於早期測試由於錯誤而沒有清理其測試替身而導致測試開始隨機失敗的問題。

Sinon 不是魔術

Sinon 執行許多操作,有時可能很難理解它的工作原理。讓我們來看看 Sinon 工作原理的一些簡單的 JavaScript 示例,以便我們可以更好地了解它的內部工作原理。這將幫助您在不同的情況下更有效地使用它。

我們也可以手動創建間諜、存根和模擬。我們使用 Sinon 的原因是它使任務變得微不足道——手動創建它們可能非常複雜,但讓我們看看它是如何工作的,以了解 Sinon 的作用。

首先,間諜本質上是一個函數包裝器:

<code class="language-javascript">var spy = sinon.spy();

//我们可以像函数一样调用间谍
spy('Hello', 'World');

//现在我们可以获取有关调用的信息
console.log(spy.firstCall.args); //输出:['Hello', 'World']
</code>

我們可以很容易地使用自定義函數獲得間諜功能。但是請注意,Sinon 的間諜提供了更廣泛的功能——包括斷言支持。這使得 Sinon 更方便。

那存根呢?

要創建一個非常簡單的存根,您可以簡單地用一個新函數替換一個函數:

<code class="language-javascript">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();
</code>

但是,Sinon 的存根提供了幾個優點:

  • 它們包含完整的間諜功能
  • 您可以使用 stub.restore() 輕鬆恢復原始行為
  • 您可以針對 Sinon 存根進行斷言

模擬只是結合了間諜和存根的行為,從而可以以不同的方式使用它們的功能。

即使 Sinon 有時看起來像是做了很多“魔術”,在大多數情況下,這也可以很容易地用您自己的代碼來完成。 Sinon 使用起來要方便得多,而不是必須為該目的編寫自己的庫。

結論

測試現實生活中的代碼有時似乎過於復雜,很容易完全放棄。但是藉助 Sinon,測試幾乎任何類型的代碼都變得輕而易舉。

只需記住主要原則:如果函數使您的測試難以編寫,請嘗試將其替換為測試替身。無論函數執行什麼操作,此原則都適用。

想要了解如何在您自己的代碼中應用 Sinon?訪問我的網站,我會向您發送我的免費現實世界中的 Sinon 指南,其中包括 Sinon 最佳實踐以及如何在不同類型的測試情況下應用它的三個現實世界示例!

關於 Sinon.js 測試的常見問題解答 (FAQ)

Sinon.js 中的模擬、間諜和存根有什麼區別?

在 Sinon.js 中,模擬、間諜和存根具有不同的用途。間諜是記錄所有調用的參數、返回值、this 的值和拋出的異常(如果有)的函數。它們可用於跟踪函數調用和響應。存根類似於間諜,但具有預編程行為。它們還會記錄有關如何調用它們的信息,但與間諜不同,它們可用於控制方法的行為,以強制方法拋出錯誤或返回特定值。模擬是具有預編程行為(如存根)以及預編程期望的假方法(如間諜)。

如何在 JavaScript 中使用 Sinon.js 進行單元測試?

Sinon.js 是一個強大的工具,用於在 JavaScript 測試中創建間諜、存根和模擬。要使用它,您首先需要將其包含在您的項目中,方法是在您的 HTML 中使用腳本標記或通過 npm 安裝它。包含後,您可以使用其 API 創建和管理間諜、存根和模擬。然後,這些可以用於隔離您正在測試的代碼並確保它按預期運行。

如何在 Sinon.js 中創建間諜?

在 Sinon.js 中創建間諜很簡單。您只需調用 sinon.spy() 函數。這將返回一個間諜函數,您可以在測試中使用它。間諜將記錄有關如何調用它的信息,然後您可以在測試中檢查這些信息。例如,您可以檢查調用間諜的次數、使用什麼參數調用它以及它返回的內容。

如何在 Sinon.js 中創建存根?

要在 Sinon.js 中創建存根,您需要調用 sinon.stub() 函數。這將返回一個存根函數,您可以在測試中使用它。存根的行為類似於間諜,記錄有關如何調用它的信息,但它還允許您控制其行為。例如,您可以使存根拋出錯誤或返回特定值。

如何在 Sinon.js 中創建模擬?

在 Sinon.js 中創建模擬涉及調用 sinon.mock() 函數。這將返回一個模擬對象,您可以在測試中使用它。模擬對象的行為類似於間諜,記錄有關如何調用它的信息,並且類似於存根,允許您控制其行為。但它還允許您設置有關如何調用它的期望。

如何將 Sinon.js 與其他測試框架一起使用?

Sinon.js 旨在與任何 JavaScript 測試框架一起使用。它提供了一個獨立的測試框架,但它也可以與 Mocha、Jasmine 和 QUnit 等其他流行的測試框架集成。 Sinon.js 文檔提供了與這些框架和其他測試框架集成的示例。

如何將存根或間諜恢復到其原始函數?

如果您已用存根或間諜替換了函數,則可以通過調用存根或間諜上的 .restore() 方法來恢復原始函數。如果您想在測試後進行清理,以確保存根或間諜不會影響其他測試,這將非常有用。

如何檢查是否使用特定參數調用了間諜?

Sinon.js 提供了幾種方法來檢查如何調用間諜。例如,您可以使用 .calledWith() 方法來檢查是否使用特定參數調用了間諜。您還可以使用 .calledOnceWith() 方法來檢查間諜是否只使用特定參數調用了一次。

如何使存根返回特定值?

您可以使用 .returns() 方法使存根返回特定值。例如,如果您有一個名為 myStub 的存根,則可以通過調用 myStub.returns('foo') 使其返回值 'foo'。

如何使存根拋出錯誤?

您可以使用 .throws() 方法使存根拋出錯誤。例如,如果您有一個名為 myStub 的存根,則可以通過調用 myStub.throws() 使其拋出錯誤。默認情況下,這將拋出一個 Error 對象,但您也可以通過將錯誤的名稱作為參數傳遞來使其拋出特定類型的錯誤。

以上是Sinon教程:使用模擬,間諜和存根的JavaScript測試的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn