Sinon hatası Zaten sarmalanmış olan işlevi sarmaya çalışıldı


92

Burada da aynı soru olmasına rağmen sorunuma cevap bulamadım, işte sorum şu:

Mocha ve chai kullanarak node js uygulamamı test ediyorum. İşlevimi tamamlamak için günah kullanıyorum.

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
  });
}

Bu testi çalıştırmayı denediğimde bana hata veriyor

Attempted to wrap getObj which is already wrapped

Ben de koymayı denedim

beforeEach(function () {
  sandbox = sinon.sandbox.create();
});

afterEach(function () {
  sandbox.restore();
});

her birinde anlatıyor, ama yine de bana aynı hatayı veriyor.


Yanıtlar:


113

Sen geri gerektiğini getObjde after()fonksiyonu, aşağıda bunu deneyin.

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();
    });
});

Yukarıda kabul edilen yolu denedikten sonra, "her şeyden önce" kancasının altında aynı hatayı alıyorum
Ashwin Hegde

@AshwinHegde, lütfen bana test kodlarını verir misin? Belki burada bir sorun bulabilirim.
zangw

1
Her birini belirtmeden tüm saplamaları geri yüklemenin bir yolu yok mu? sinon.restoreAll();Bir koçanı geri yüklemeyi unutmadığınızdan emin olmak için tüm testlerden sonra çalıştırılabilecek bir a sahip olmak harika olurdu .
Luke

afterEach (() => {sinon.verifyAndRestore ();});
Sam T

20

Bu hata, saplama işlevinin düzgün şekilde geri yüklenmemesinden kaynaklanmaktadır. Korumalı alanı kullanın ve ardından korumalı alanı kullanarak saplama oluşturun. Paket içindeki her testten sonra korumalı alanı geri yükleyin

  beforeEach(() => {
      sandbox = sinon.createSandbox();
      mockObj = sandbox.stub(testApp, 'getObj', fake_function)
  });

  afterEach(() => {
      sandbox.restore();
  });

1
dostum, hayatımı kurtardı)
Yegor Zaremba

Bu benim için çalıştı. Bunun kabul edilen cevap olması gerektiğini düşünüyorum.
Daniel Kaplan

Sarma işlevleriyle birden fazla test yaptım ve her birini kullanmam gerekiyor .
Richard

Benim durumumda, bu doğru cevaptı, çünkü belirli bir yöntemi değil, bütün bir nesneyi casusluk ediyordum, bu yüzden geri yükleyemedim.
Edison Spencer

11

Bir nesnenin tüm yöntemlerini geri yüklemeniz gereken durumlar için sinon.restore(obj),.

Misal:

before(() => {
    userRepositoryMock = sinon.stub(userRepository);
});

after(() => {
    sinon.restore(userRepository);
});

1
Nesne üzerinde işlevler saplarken bu benim için işe yaramadı. Kabul edilen yanıtın gösterdiği gibi işlev başına geri yüklemem gerekiyordu.
Ian Robertson

7
sinon.restore (), Sinon v2'de kullanımdan kaldırıldı ve daha sonra kaldırıldı. // Previously sinon.restore(stubObject); // Typescript (stubObject as any).restore(); // Javascript stubObject.restore();
MatthiasSommer

6

Ben de buna Mocha'nın before () ve after () kancalarını kullanarak vuruyordum. Ayrıca her yerde belirtildiği gibi restore () kullanıyordum. Tek test dosyası sorunsuz çalıştı, birden çok test dosyası çalışmadı. Sonunda Mocha kök seviyesi kancaları hakkında buldum : Kendi tarifimde () öncesi () ve sonrası () yoktu. Bu nedenle, kök düzeyinde before () olan tüm dosyaları bulur ve herhangi bir teste başlamadan önce bunları yürütür.

Bu nedenle, benzer bir modele sahip olduğunuzdan emin olun:

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');
  });
});

3

Stub'ların 'beforeEach' içinde başlatılması ve 'afterEach' içinde geri yüklenmesi önerilir. Ama maceracı hissediyorsanız, aşağıdakiler de işe yarar.

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();
  });
}

3

Sandbox ile bile size hata verebilir. Özellikle testler ES6 sınıfları için paralel olarak çalıştırıldığında.

const sb = sandbox.create();

before(() => {
  sb.stub(MyObj.prototype, 'myFunc').callsFake(() => {
    return 'whatever';
  });
});
after(() => {
  sb.restore();
});

Bu, başka bir test, MyFunc'u Prototipten saplamaya çalışıyorsa aynı hatayı verebilir. Bunu düzelttim ama bundan gurur duymuyorum ...

const sb = sandbox.create();

before(() => {
  MyObj.prototype.myFunc = sb.stub().callsFake(() => {
    return 'whatever';
  });
});
after(() => {
  sb.restore();
});

3

Bu sorunla karşılaşan herkes için, nesnenin tamamını takip ederseniz veya casusluk yaparsanız ve daha sonra

sandbox.restore ()

Yine de hatayı alacaksınız. Tek tek yöntemleri saplamanız / gözetlemeniz gerekir.

Neyin yanlış olduğunu anlamaya çalışmakla sonsuza kadar harcadım.

sinon-7.5.0


2

Buna casuslarla rastladım. Bu davranış, sinon'u birlikte çalışmayı oldukça esnek hale getirir. Yenisini ayarlamadan önce mevcut herhangi bir casusu kaldırmaya çalışan bir yardımcı işlev oluşturdum. Bu şekilde önceki / sonraki durum hakkında endişelenmeme gerek kalmaz. Benzer bir yaklaşım taslaklar için de işe yarayabilir.

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);
};


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);
    }

ve bu işlevi testlerde taslak oluştururken kullanın. 'Sinon hatası Zaten sarmalanmış olan işlevi sarmaya çalıştı' hatasını çözecektir.

misal:

stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.