programing

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

codeshow 2023. 9. 4. 20:49
반응형

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

여기에도 같은 질문이 있지만 저는 제 문제에 대한 답을 찾을 수 없었습니다. 그래서 제 질문은 다음과 같습니다.

나는 모카와 차이를 사용하여 노드 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 getObj which is already wrapped

퍼팅도 해봤어요.

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

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

각각의 묘사에서, 그러나 여전히 나에게 같은 오류를 줍니다.

복원해야 합니다.getObjafter()기능, 아래와 같이 해보세요.

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

2022/01/22 업데이트

Sinon의 sanbox를 사용하여 스텁 모크를 만들 수 있습니다.sandbox.stub()를 통해 생성된 모든 가짜를 복구합니다.sandbox.restore()Arjun Malik은 좋은 예를 들어줍니다.

이 오류는 스텁 기능을 제대로 복원하지 못해 발생합니다.샌드박스를 사용한 다음 샌드박스를 사용하여 스텁을 생성합니다.제품군 내부에서 각 테스트 후 샌드박스

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

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

한 개체의 모든 메서드를 복원해야 하는 경우에는sinon.restore(obj).

예:

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

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

저도 모카의 앞()과 뒤() 훅을 이용해서 이것을 치고 있었습니다.저는 또한 모든 곳에서 언급된 restore()를 사용하고 있었습니다.단일 테스트 파일은 정상적으로 실행되었지만 여러 파일은 정상적으로 실행되지 않았습니다.마지막으로 Mocha 루트 레벨 후크에 대해 찾았습니다.저는 제 자신의 묘사() 안에 전()과 후()를 가지고 있지 않았습니다.따라서 루트 수준에서 앞()이 있는 모든 파일을 찾아 테스트를 시작하기 전에 실행합니다.

따라서 유사한 패턴이 있는지 확인하십시오.

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

한 시간 정도 걸려서 알아냈거든요

두 개 이상의 테스트 파일이 있지만 어떤 시도를 해도 "이미 포장된" 오류가 계속 발생하는 경우에는beforeEach그리고.afterEach stub/replace 핸들러가 테스트 파일의 내부에 있습니다.describe블록으로 막다

만약 당신이 그것들을 글로벌 테스트 범위, 즉 외부에 둔다면.describe('my test description', () => {})건설, 시논은 두 번 시도하고 이것을 던질 것입니다.

전체 개체를 스텁(stub) 또는 스파이 활동을 수행하고 나중에 수행하는 경우 이 문제가 발생할 수 있습니다.

sandbox.restore 설정

계속 오류가 발생할 것입니다.당신은 개별적인 방법을 비밀리에 처리해야 합니다.

나는 무엇이 잘못되었는지 알아내려고 노력하면서 영원히 낭비했습니다.

sinon-7.5.0

스텁은 'Before Each'에서 초기화하고 'After Each'에서 복원하는 것이 좋습니다.하지만 여러분이 모험심을 느끼는 경우, 다음과 같은 것들도 효과가 있습니다.

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

샌드박스를 사용하더라도 오류가 발생할 수 있습니다.특히 ES6 클래스에 대해 테스트가 병렬로 실행되는 경우에는 더욱 그렇습니다.

const sb = sandbox.create();

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

다른 테스트에서 프로토타입에서 myFunc를 스텁(stub)하려고 할 경우 동일한 오류가 발생할 수 있습니다.그걸 고칠 수는 있었지만 자랑스럽지는 않아요...

const sb = sandbox.create();

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

저는 스파이들과 우연히 마주쳤어요이러한 행동은 죄악을 함께 일하기에 상당히 융통성이 없게 만듭니다.새로운 스파이를 설정하기 전에 기존 스파이를 제거하는 도우미 기능을 만들었습니다.그래야 전후 상태에 대해 걱정할 필요가 없습니다.스텁에도 유사한 접근 방식이 적용될 수 있습니다.

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

함수가 다른 곳에서 스파이 활동을 했기 때문에 이 동작을 만났습니다.그래서 저는 아래와 같이 미리 정의된 스파이를 제거하고 저만의 스파이를 만들었습니다.

obj.func.restore()
let spy = sinon.spy(obj, 'func')

그건 효과가 있다.

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 error Attempted to wraped function' 오류가 해결됩니다.

예:

stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));

언급URL : https://stackoverflow.com/questions/36074631/sinon-error-attempted-to-wrap-function-which-is-already-wrapped

반응형