我正在将 Mocha 与 Sinon 一起使用,并尝试测试递归调用(斐波那契)。我的代码是:
'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) {
我收到以下错误:
类型错误:分配给常量变量。
这符合预期,但它提出了一个问题,我如何测试使用 Sinon 声明为 const 的递归函数?
已编辑 Jasmine 有一个名为 .callThrough() 的东西,它似乎允许测试递归函数。
在我看来,没有办法在诗农身上复制这种行为?我查看了以下错误报告/功能请求:
https://github.com/sinonjs/sinon/issues/668
https://github.com/sinonjs/sinon/issues/989
谢谢。
最佳答案
直接在函数上调用 sinon.spy
会在原始函数周围创建一个包装器,用于跟踪调用和返回值,但不会修改它,因此您不需要记住它并恢复它。
有了这些信息,显而易见的答案就是简单地将你的 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);
});
});
此方法对于非递归函数效果很好,但您可能会注意到,当第一个断言通过时,第二个断言失败,仅对 spy 进行了 1 次调用。
问题是这里还有一个问题在起作用。函数 fib 直接调用自身,并且不会通过用 sinon.spy
包装该函数来跟踪这些直接递归调用。
有关此问题的更多详细信息以及相应的解决方案,请参见 the answer here .
关于javascript - Sinon Spies——测试递归(可能还有 const)函数表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51696624/