Ошибка Sinon Попытка обернуть функцию, которая уже завернута

Хотя здесь есть один и тот же вопрос, но я не мог найти ответ на мою проблему, поэтому здесь возникает мой вопрос:

Я тестирую мое приложение node js, используя mocha и chai. Я использую 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 getDbObj which is already wrapped

Я также попытался поставить

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

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

в каждом описывают, но все же дают мне ту же ошибку.

Ответы

Ответ 1

Вы должны восстановить функцию getObj в after(), попробуйте, как показано ниже.

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

Ответ 2

В случаях, когда вам нужно восстановить все методы одного объекта, вы можете использовать sinon.restore(obj).

Пример:

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

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

Ответ 3

Я также ударил это с помощью хуков Mocha before() и after(). Я также использовал restore(), как уже упоминалось. Один тестовый файл работал нормально, несколько - нет. Наконец-то нашлось о крючках корневого уровня Mocha: у меня не было своих before() и after() внутри моего собственного description(). Таким образом, он находит все файлы с 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');
  });
});

Ответ 4

Рекомендуется инициализировать заглушки в '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();
  });
}

Ответ 5

Эта ошибка связана с неправильным восстановлением функции заглушки. Используйте песочницу, а затем создайте заглушку, используя песочницу. После тестового набора восстановите песочницу.

  before(() => {
      sandbox         = sinon.sandbox.create();
      mockObj         = sandbox.stub(testApp, 'getObj', fake_function)
  });
  after(() => {
      sandbox.restore();
  });

Ответ 6

Даже с песочницей это может привести к ошибке. Особенно, когда тесты проводятся параллельно для классов ES6.

const sb = sandbox.create();

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

это может вызвать ту же ошибку, если другой тест пытается заглушить myFunc из Prototype. Я смог это исправить, но я не горжусь этим...

const sb = sandbox.create();

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