web-dev-qa-db-ja.com

Sinonエラー既にラップされている関数をラップしようとしました

ここには同じ質問がありますが、私の問題に対する答えが見つかりませんでしたので、ここに私の質問があります:

Mochaとchaiを使用して、ノードjsアプリをテストしています。私は自分の機能をラップするために罪を使用しています。

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

それぞれを説明しますが、それでも同じエラーが表示されます。

65
Rohit Vyavahare

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

1つのオブジェクトのすべてのメソッドを復元する必要がある場合は、sinon.restore(obj)を使用できます。

例:

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

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

このエラーは、スタブ関数を適切に復元しないことが原因です。サンドボックスを使用してから、サンドボックスを使用してスタブを作成します。テストスイートの後、サンドボックスを復元します。

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

また、Mochaのbefore()およびafter()フックを使用してこれをヒットしていました。私はどこでも言及したようにrestore()も使用していました。単一のテストファイルは正常に実行され、複数のテストファイルは実行されませんでした。最後に Mocha root-level-hooks について見つけました:before()とafter()を自分のdescribe()の中に入れていません。したがって、ルートレベルで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');
  });
});
5
Wilfred Dittmer

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

サンドボックスを使用しても、エラーが発生する可能性があります。特に、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();
});
2
Tonino

私はスパイに遭遇しました。この動作により、sinonは非常に柔軟性に欠けます。新しいスパイを設定する前に、既存のスパイを削除しようとするヘルパー関数を作成しました。そうすれば、前/後の状態を心配する必要はありません。同様のアプローチがスタブでも機能する場合があります。

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
Phil