簡體   English   中英

Sinon Spies —測試遞歸(可能是const)函數表達式

[英]Sinon Spies — Testing a recursive (and possibly const) function expression

我正在與Sinon一起使用Mocha,並嘗試測試遞歸調用(fibonacci)。 我的代碼是:

'use strict';

let sinon = require('sinon'),
    chai = require('chai'),
    expect = chai.expect;

chai.use(require('sinon-chai'));

let fib = function (n) {
    if (n === 0) {
        return 0;
    } else if (n === 1) {
        return 1;
    } else {
        return fib(n-2) + fib(n-1);
    }
};

describe('fib', function() {
        it('should repeat calculations', function() {
            let originalFib = fib;
            fib = sinon.spy(fib)

            expect(fib(6)).to.equal(8);
            expect(fib).to.have.callCount(25);

            fib = originalFib;
        });
});

此代碼按原樣工作,但是,如果我替換以下行:

let fib = function (n) {

與:

const fib = function (n) {

我收到以下錯誤:

TypeError:分配給常數變量。

這是預期的,但提出了一個問題,我將如何測試使用Sinon聲明為const的遞歸函數?

編輯的茉莉花有一個叫做.callThrough()的東西,它似乎允許測試遞歸函數。

在我看來,沒有辦法與詩乃復制這種行為嗎? 我查看了以下錯誤報告/功能要求:

https://github.com/sinonjs/sinon/issues/668

https://github.com/sinonjs/sinon/issues/989

謝謝。

直接在函數上調用sinon.spy會在原始函數周圍創建一個包裝器,該包裝器可跟蹤調用和返回的值,但不會對其進行修改,因此您無需記住它並進行還原。

有了這些信息,顯而易見的答案就是簡單地給您的間諜起個別的名字:

describe('fib', function() {
  it('should repeat calculations', function() {
    const spy = sinon.spy(fib);

    expect(spy(6)).to.equal(8);
    expect(spy).to.have.callCount(25);
  });
});

這種方法適用於非遞歸函數,但是您可能會注意到,盡管第一個斷言通過了,但是第二個失敗了,只進行了一次間諜調用。

問題是這里還有另外一個問題。 函數fib直接調用自身,通過使用sinon.spy包裝該函數不會跟蹤那些直接的遞歸調用。

有關此問題的更多詳細信息以及相應的解決方案,請參見此處的答案

將代碼更改為const fib = function(n)時的主要問題是因為您擁有此后續代碼fib = sinon.spy(fib) 我們無法使用const重新聲明任何變量的賦值。

根據我的經驗,對於這種測試,我覺得沒有必要使用spy除非您有其他函數可以在fib內調用。 我們可以執行並檢查所有可能情況的值。

'use strict';

const sinon = require('sinon'),
      chai = require('chai'),
      expect = chai.expect;

chai.use(require('sinon-chai'));

const fib = function (n) {
  if (n === 0) {
    return 0;
  } else if (n === 1) {
    return 1;
  } else {
    return fib(n - 2) + fib(n - 1);
  }
};

describe('fib', function () {
  it('should repeat calculations', function () {
    expect(fib(0)).to.equal(0); // add more cases
    expect(fib(1)).to.equal(1);
    expect(fib(6)).to.equal(8);
  });
});

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM