Sinon 错误尝试包装已经包装的函数
Sinon error Attempted to wrap function which is already wrapped
虽然这里也有同样的问题,但我找不到问题的答案所以我的问题是:
我正在使用 mocha 和 chai 测试我的节点 js 应用程序。我正在使用 sinion 来包装我的函数。
describe('App Functions', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('get results',function(done) {
testApp.someFun
});
}
describe('App Errors', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('throws errors',function(done) {
testApp.someFun
});
}
当我尝试 运行 这个测试时它给我错误
Attempted to wrap getObj which is already wrapped
我也试过
beforeEach(function () {
sandbox = sinon.sandbox.create();
});
afterEach(function () {
sandbox.restore();
});
在每个描述中,但仍然给我同样的错误。
您应该恢复 after()
函数中的 getObj
,请按以下方法尝试。
describe('App Functions', function(){
var mockObj;
before(function () {
mockObj = sinon.stub(testApp, 'getObj', () => {
console.log('this is sinon test 1111');
});
});
after(function () {
testApp.getObj.restore(); // Unwraps the spy
});
it('get results',function(done) {
testApp.getObj();
});
});
describe('App Errors', function(){
var mockObj;
before(function () {
mockObj = sinon.stub(testApp, 'getObj', () => {
console.log('this is sinon test 1111');
});
});
after( function () {
testApp.getObj.restore(); // Unwraps the spy
});
it('throws errors',function(done) {
testApp.getObj();
});
});
更新 2022/01/22
使用sinon's sanbox you could created stub mocks with sandbox.stub()
and restores all fakes created through sandbox.restore()
, Arjun Malik give an good
如果需要恢复一个对象的所有方法,可以使用sinon.restore(obj)
。
示例:
before(() => {
userRepositoryMock = sinon.stub(userRepository);
});
after(() => {
sinon.restore(userRepository);
});
我还使用了 Mocha 的 before() 和 after() 钩子来解决这个问题。我也在使用到处都提到的 restore() 。单个测试文件 运行 很好,多个没有。
终于找到了 Mocha root-level-hooks:我自己的 describe() 中没有 before() 和 after()。所以它会在根级别找到所有带有 before() 的文件,并在开始任何测试之前执行这些文件。
所以请确保您有类似的模式:
describe('my own describe', () => {
before(() => {
// setup stub code here
sinon.stub(myObj, 'myFunc').callsFake(() => {
return 'bla';
});
});
after(() => {
myObj.myFunc.restore();
});
it('Do some testing now', () => {
expect(myObj.myFunc()).to.be.equal('bla');
});
});
建议在 'beforeEach' 中初始化存根并在 'afterEach' 中恢复它们。但如果您喜欢冒险,以下方法也适用。
describe('App Functions', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('get results',function(done) {
testApp.someFun
mockObj .restore();
});
}
describe('App Errors', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('throws errors',function(done) {
testApp.someFun
mockObj .restore();
});
}
此错误是由于未正确恢复存根功能所致。使用沙箱,然后使用沙箱创建存根。套件内每次测试后,恢复沙箱
beforeEach(() => {
sandbox = sinon.createSandbox();
mockObj = sandbox.stub(testApp, 'getObj', fake_function)
});
afterEach(() => {
sandbox.restore();
});
即使使用沙箱,它也可能会给您带来错误。尤其是在为 ES6 类.
并行测试 运行 时
const sb = sandbox.create();
before(() => {
sb.stub(MyObj.prototype, 'myFunc').callsFake(() => {
return 'whatever';
});
});
after(() => {
sb.restore();
});
如果另一个测试试图从原型中存根 myFunc,这可能会引发相同的错误。
我能够解决这个问题,但我并不为此感到自豪...
const sb = sandbox.create();
before(() => {
MyObj.prototype.myFunc = sb.stub().callsFake(() => {
return 'whatever';
});
});
after(() => {
sb.restore();
});
我运行带间谍进去了。这种行为使得 sinon 使用起来非常不灵活。我创建了一个辅助函数,试图在设置新间谍之前删除任何现有间谍。这样我就不必担心任何 before/after 状态。类似的方法也可能适用于存根。
import sinon, { SinonSpy } from 'sinon';
/**
* When you set a spy on a method that already had one set in a previous test,
* sinon throws an "Attempted to wrap [function] which is already wrapped" error
* rather than replacing the existing spy. This helper function does exactly that.
*
* @param {object} obj
* @param {string} method
*/
export const spy = function spy<T>(obj: T, method: keyof T): SinonSpy {
// try to remove any existing spy in case it exists
try {
// @ts-ignore
obj[method].restore();
} catch (e) {
// noop
}
return sinon.spy(obj, method);
};
对于任何 运行 陷入此问题的人来说,如果您对整个对象进行存根或监视,然后您又
sandbox.restore()
您仍然会收到错误消息。您必须 stub/spy 各个方法。
我一直在浪费时间试图找出问题所在。
sinon-7.5.0
function stub(obj, method) {
// try to remove any existing stub in case it exists
try {
obj[method].restore();
} catch (e) {
// eat it.
}
return sinon.stub(obj, method);
}
并在测试中创建存根时使用此函数。它将解决 'Sinon error Attempted to wrap function which is already wrapped' 错误。
示例:
stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
提醒一下,因为这花了我大约一个小时才弄明白:
如果您有两个(或更多)测试文件,并且发现自己 仍然 遇到“已包装”错误,无论您尝试什么,请确保您的 beforeEach
和 afterEach
存根/替换处理程序在测试文件的 describe
块内。
如果你把它们放在全局测试范围内,即在 describe('my test description', () => {})
结构之外,sinon 会尝试两次并抛出这个。
我遇到这种行为是因为该函数在其他地方被监视。因此,我删除了如下所示的预定义间谍并创建了我自己的间谍。
obj.func.restore()
let spy = sinon.spy(obj, 'func')
有效。
虽然这里也有同样的问题,但我找不到问题的答案所以我的问题是:
我正在使用 mocha 和 chai 测试我的节点 js 应用程序。我正在使用 sinion 来包装我的函数。
describe('App Functions', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('get results',function(done) {
testApp.someFun
});
}
describe('App Errors', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('throws errors',function(done) {
testApp.someFun
});
}
当我尝试 运行 这个测试时它给我错误
Attempted to wrap getObj which is already wrapped
我也试过
beforeEach(function () {
sandbox = sinon.sandbox.create();
});
afterEach(function () {
sandbox.restore();
});
在每个描述中,但仍然给我同样的错误。
您应该恢复 after()
函数中的 getObj
,请按以下方法尝试。
describe('App Functions', function(){
var mockObj;
before(function () {
mockObj = sinon.stub(testApp, 'getObj', () => {
console.log('this is sinon test 1111');
});
});
after(function () {
testApp.getObj.restore(); // Unwraps the spy
});
it('get results',function(done) {
testApp.getObj();
});
});
describe('App Errors', function(){
var mockObj;
before(function () {
mockObj = sinon.stub(testApp, 'getObj', () => {
console.log('this is sinon test 1111');
});
});
after( function () {
testApp.getObj.restore(); // Unwraps the spy
});
it('throws errors',function(done) {
testApp.getObj();
});
});
更新 2022/01/22
使用sinon's sanbox you could created stub mocks with sandbox.stub()
and restores all fakes created through sandbox.restore()
, Arjun Malik give an good
如果需要恢复一个对象的所有方法,可以使用sinon.restore(obj)
。
示例:
before(() => {
userRepositoryMock = sinon.stub(userRepository);
});
after(() => {
sinon.restore(userRepository);
});
我还使用了 Mocha 的 before() 和 after() 钩子来解决这个问题。我也在使用到处都提到的 restore() 。单个测试文件 运行 很好,多个没有。 终于找到了 Mocha root-level-hooks:我自己的 describe() 中没有 before() 和 after()。所以它会在根级别找到所有带有 before() 的文件,并在开始任何测试之前执行这些文件。
所以请确保您有类似的模式:
describe('my own describe', () => {
before(() => {
// setup stub code here
sinon.stub(myObj, 'myFunc').callsFake(() => {
return 'bla';
});
});
after(() => {
myObj.myFunc.restore();
});
it('Do some testing now', () => {
expect(myObj.myFunc()).to.be.equal('bla');
});
});
建议在 'beforeEach' 中初始化存根并在 'afterEach' 中恢复它们。但如果您喜欢冒险,以下方法也适用。
describe('App Functions', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('get results',function(done) {
testApp.someFun
mockObj .restore();
});
}
describe('App Errors', function(){
let mockObj = sinon.stub(testApp, 'getObj', (dbUrl) => {
//some stuff
});
it('throws errors',function(done) {
testApp.someFun
mockObj .restore();
});
}
此错误是由于未正确恢复存根功能所致。使用沙箱,然后使用沙箱创建存根。套件内每次测试后,恢复沙箱
beforeEach(() => {
sandbox = sinon.createSandbox();
mockObj = sandbox.stub(testApp, 'getObj', fake_function)
});
afterEach(() => {
sandbox.restore();
});
即使使用沙箱,它也可能会给您带来错误。尤其是在为 ES6 类.
并行测试 运行 时const sb = sandbox.create();
before(() => {
sb.stub(MyObj.prototype, 'myFunc').callsFake(() => {
return 'whatever';
});
});
after(() => {
sb.restore();
});
如果另一个测试试图从原型中存根 myFunc,这可能会引发相同的错误。 我能够解决这个问题,但我并不为此感到自豪...
const sb = sandbox.create();
before(() => {
MyObj.prototype.myFunc = sb.stub().callsFake(() => {
return 'whatever';
});
});
after(() => {
sb.restore();
});
我运行带间谍进去了。这种行为使得 sinon 使用起来非常不灵活。我创建了一个辅助函数,试图在设置新间谍之前删除任何现有间谍。这样我就不必担心任何 before/after 状态。类似的方法也可能适用于存根。
import sinon, { SinonSpy } from 'sinon';
/**
* When you set a spy on a method that already had one set in a previous test,
* sinon throws an "Attempted to wrap [function] which is already wrapped" error
* rather than replacing the existing spy. This helper function does exactly that.
*
* @param {object} obj
* @param {string} method
*/
export const spy = function spy<T>(obj: T, method: keyof T): SinonSpy {
// try to remove any existing spy in case it exists
try {
// @ts-ignore
obj[method].restore();
} catch (e) {
// noop
}
return sinon.spy(obj, method);
};
对于任何 运行 陷入此问题的人来说,如果您对整个对象进行存根或监视,然后您又
sandbox.restore()
您仍然会收到错误消息。您必须 stub/spy 各个方法。
我一直在浪费时间试图找出问题所在。
sinon-7.5.0
function stub(obj, method) {
// try to remove any existing stub in case it exists
try {
obj[method].restore();
} catch (e) {
// eat it.
}
return sinon.stub(obj, method);
}
并在测试中创建存根时使用此函数。它将解决 'Sinon error Attempted to wrap function which is already wrapped' 错误。
示例:
stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
提醒一下,因为这花了我大约一个小时才弄明白:
如果您有两个(或更多)测试文件,并且发现自己 仍然 遇到“已包装”错误,无论您尝试什么,请确保您的 beforeEach
和 afterEach
存根/替换处理程序在测试文件的 describe
块内。
如果你把它们放在全局测试范围内,即在 describe('my test description', () => {})
结构之外,sinon 会尝试两次并抛出这个。
我遇到这种行为是因为该函数在其他地方被监视。因此,我删除了如下所示的预定义间谍并创建了我自己的间谍。
obj.func.restore()
let spy = sinon.spy(obj, 'func')
有效。