Sinon 오류 이미 래핑 된 함수를 래핑하려고했습니다.


91

여기에 같은 질문이 있지만 내 문제에 대한 답을 찾을 수 없으므로 여기에 내 질문이 있습니다.

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

각 설명에서 여전히 동일한 오류가 발생합니다.


당신은 게시물의 하단에 설명을 찾을 수 있습니다 여기에
Nir 씨 Alfasi에게

답변:


113

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

위의 허용 방법을 시도 후, 나는 후크 "모든 전에"아래 같은 오류를 얻고있다
애쉬 윈 Hegde

@AshwinHegde, 테스트 코드를 알려주시겠습니까? 여기서 문제를 찾을 수있을 것입니다.
zangw

1
각 스텁을 지정하지 않고 모든 스텁을 복원 할 방법이 없습니까? sinon.restoreAll();스텁을 복원하는 것을 잊지 않도록 모든 테스트 후에 실행할 수 있는를 갖는 것이 좋을 것 입니다.
Luke

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

20

이 오류는 스텁 기능을 제대로 복원하지 않았기 때문입니다. 샌드 박스를 사용한 다음 샌드 박스를 사용하여 스텁을 만듭니다. Suite 내부의 각 테스트 후 샌드 박스를 복원합니다.

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

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

1
친구, 내 인생) 저장
예고 르 Zaremba

이것은 나를 위해 일했습니다. 나는 이것이 받아 들여진 대답이어야한다고 생각한다.
Daniel Kaplan

랩핑 기능을 사용하여 여러 테스트를 수행했으며 afterEach 를 사용해야 합니다 .
Richard

제 경우에는 특정 방법이 아닌 전체 개체를 감시했기 때문에 이것이 정답이었습니다. 그래서 복원 할 수 없었습니다.
Edison Spencer

11

한 개체의 모든 방법을 복원해야하는 경우 sinon.restore(obj).

예:

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

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

1
이것은 객체에서 함수를 스터 빙 할 때 저에게 효과적이지 않았습니다. 나는 받아 들여진 대답처럼 기능별로 복원해야했습니다.
Ian Robertson

7
sinon.restore ()는 Sinon v2에서 더 이상 사용되지 않으며 나중에 제거되었습니다. // Previously sinon.restore(stubObject); // Typescript (stubObject as any).restore(); // Javascript stubObject.restore();
MatthiasSommer

6

나는 또한 Mocha의 before () 및 after () 후크를 사용하여 이것을 치고있었습니다. 나는 또한 모든 곳에서 언급했듯이 restore ()를 사용하고 있었다. 단일 테스트 파일은 정상적으로 실행되었지만 여러 개는 실행되지 않았습니다. 마지막으로 Mocha 루트 레벨 후크 에 대해 발견했습니다 . 따라서 루트 수준에서 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');
  });
});

3

'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

샌드 박스를 사용하더라도 오류가 발생할 수 있습니다. 특히 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();
});

3

이 문제에 직면 한 모든 사람을 위해 전체 개체에 대해 스텁 또는 스파이를 수행하고 나중에

sandbox.restore ()

여전히 오류가 발생합니다. 개별 메서드를 스텁 / 스파이해야합니다.

나는 무엇이 잘못되었는지 알아 내려고 영원히 낭비했다.

sinon-7.5.0


2

나는 스파이와 함께 이것을 만났다. 이 동작은 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
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 오류 이미 래핑 된 함수 래핑 시도'오류를 해결합니다.

예:

stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.