Aunque hay una misma pregunta aquí, pero no pude encontrar la respuesta a mi problema, aquí va mi pregunta:
Estoy probando mi aplicación node js usando mocha y chai. Estoy usando sinion para envolver mi función.
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
});
}
Cuando intento ejecutar esta prueba, me da un error
Attempted to wrap getObj which is already wrapped
También intenté poner
beforeEach(function () {
sandbox = sinon.sandbox.create();
});
afterEach(function () {
sandbox.restore();
});
en cada descripción, pero todavía me da el mismo error.
Respuestas:
Debe restaurar la función
getObj
inafter()
, inténtelo de la siguiente manera.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(); }); });
fuente
sinon.restoreAll();
archivo que pudiera ejecutarse después de todas las pruebas solo para asegurarse de que no se olvide de restaurar un código auxiliar.Este error se debe a que no se ha restaurado correctamente la función stub. Use sandbox y luego cree el stub usando sandbox. Después de cada prueba dentro de la suite, restaure la caja de arena
beforeEach(() => { sandbox = sinon.createSandbox(); mockObj = sandbox.stub(testApp, 'getObj', fake_function) }); afterEach(() => { sandbox.restore(); });
fuente
Para los casos en los que necesite restaurar todos los métodos de un objeto, puede usar la extensión
sinon.restore(obj)
.Ejemplo:
before(() => { userRepositoryMock = sinon.stub(userRepository); }); after(() => { sinon.restore(userRepository); });
fuente
// Previously sinon.restore(stubObject); // Typescript (stubObject as any).restore(); // Javascript stubObject.restore();
También estaba golpeando esto usando los ganchos antes () y después () de Mocha. También estaba usando restore () como se menciona en todas partes. Un solo archivo de prueba funcionó bien, varios no. Finalmente encontré sobre los ganchos de nivel de raíz de Mocha : no tenía mi antes () y después () dentro de mi propio describe (). Por lo tanto, encuentra todos los archivos con before () en el nivel raíz y los ejecuta antes de iniciar cualquier prueba.
Así que asegúrese de tener un patrón similar:
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'); }); });
fuente
Se recomienda inicializar los stubs en 'beforeEach' y restaurarlos en 'afterEach'. Pero en caso de que se sienta aventurero, lo siguiente también funciona.
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(); }); }
fuente
Incluso con sandbox podría darte el error. Especialmente cuando las pruebas se ejecutan en paralelo para las clases de ES6.
const sb = sandbox.create(); before(() => { sb.stub(MyObj.prototype, 'myFunc').callsFake(() => { return 'whatever'; }); }); after(() => { sb.restore(); });
esto podría arrojar el mismo error si otra prueba intenta eliminar myFunc del Prototype. Pude arreglar eso pero no estoy orgulloso de eso ...
const sb = sandbox.create(); before(() => { MyObj.prototype.myFunc = sb.stub().callsFake(() => { return 'whatever'; }); }); after(() => { sb.restore(); });
fuente
Para cualquiera que se encuentre con este problema, si detecta o espía todo el objeto, y luego lo hace
Seguirá recibiendo el error. Tienes que eliminar / espiar los métodos individuales.
Perdí para siempre tratando de averiguar qué estaba mal.
sinon-7.5.0
fuente
Me encontré con esto con espías. Este comportamiento hace que sinon sea bastante inflexible para trabajar. Creé una función de ayuda que intenta eliminar cualquier espía existente antes de configurar uno nuevo. De esa manera no tengo que preocuparme por ningún estado antes / después. Un enfoque similar también podría funcionar para los talones.
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); };
fuente
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); }
y use esta función cuando cree stubs en pruebas. Resolverá el error 'Sinon error Intento de envolver la función que ya está envuelta'.
ejemplo:
stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
fuente