सिनॉन त्रुटि फ़ंक्शन को लपेटने का प्रयास किया गया है जो पहले से ही लपेटा हुआ है


91

हालाँकि यहाँ एक ही प्रश्न है, लेकिन मुझे अपनी समस्या का उत्तर नहीं मिला, इसलिए यहाँ मेरा प्रश्न है:

मैं मोचा और ची का उपयोग करके अपने नोड जेएस ऐप का परीक्षण कर रहा हूं। मैं अपने कार्य को पूरा करने के लिए पाप का उपयोग कर रहा हूं।

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

प्रत्येक वर्णन में, लेकिन फिर भी मुझे वही त्रुटि दे रहा है।


जवाबों:


113

आप को बहाल करना चाहिए 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();
    });
});

उपरोक्त स्वीकृत तरीके से प्रयास करने के बाद, मुझे "सभी" हुक से पहले एक ही त्रुटि मिल रही है
अश्विन हेगड़े

@AshwinHegde, क्या आप मुझे अपना परीक्षण कोड दे सकते हैं? शायद मुझे यहाँ कुछ मुद्दा मिल जाए।
ज़ंगव

1
क्या हर एक को निर्दिष्ट किए बिना सभी स्टब्स को पुनर्स्थापित करने का कोई तरीका नहीं है? यह सुनिश्चित करने के लिए बहुत अच्छा होगा sinon.restoreAll();कि सभी परीक्षणों के बाद चलाया जा सकता है यह सुनिश्चित करने के लिए कि आप स्टब को बहाल करना नहीं भूलते हैं।
ल्यूक

afterEach () (> = {sinon.verifyAndRestore ();});
सैम टी

20

यह त्रुटि स्टब फ़ंक्शन को ठीक से पुनर्स्थापित नहीं करने के कारण है। सैंडबॉक्स का उपयोग करें और फिर सैंडबॉक्स का उपयोग करके स्टब बनाएं। सुइट के अंदर प्रत्येक परीक्षण के बाद, सैंडबॉक्स को पुनर्स्थापित करें

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

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

1
यार, मेरी जान बचाई)
येगोर ज़रेम्बा

इसने मेरे लिए काम किया। मुझे ऐसा लगता है कि यह स्वीकृत उत्तर होना चाहिए।
डैनियल कपलान

रैपिंग फ़ंक्शंस के साथ मेरे पास कई परीक्षण थे और इसके बाद उपयोग करने की आवश्यकता थी
रिचर्ड

मेरे मामले में, यह सही उत्तर था, क्योंकि मैं एक पूरी वस्तु की जासूसी कर रहा था और कोई विशिष्ट विधि नहीं थी, इसलिए मैं बहाल नहीं कर सका।
एडिसन स्पेंसर

11

ऐसे मामलों के लिए जहां आपको एक वस्तु के सभी तरीकों को पुनर्स्थापित करने की आवश्यकता होती है, आप इसका उपयोग कर सकते हैं sinon.restore(obj)

उदाहरण:

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

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

1
यह मेरे लिए काम नहीं किया जब वस्तु पर कार्य ठप। मुझे स्वीकार किए गए उत्तर शो की तरह प्रति फ़ंक्शन को पुनर्स्थापित करना पड़ा।
इयान रॉबर्टसन

7
sinon.restore () Sinon v2 में पदावनत किया गया और बाद में हटा दिया गया। // Previously sinon.restore(stubObject); // Typescript (stubObject as any).restore(); // Javascript stubObject.restore();
MatthiasSommer

6

मैं भी मोचा के पहले () और बाद () हुक का उपयोग करके इसे मार रहा था। मैं भी पुनर्स्थापना () का उपयोग कर रहा था जैसा कि हर जगह उल्लेख किया गया है। एकल परीक्षण फ़ाइल ठीक-ठाक चली, कई नहीं चली। अंत में मोचा रूट-स्तर-हुक के बारे में पाया गया : मेरे पास मेरे पहले () और बाद में () मेरे अपने विवरण () के अंदर नहीं थे। इसलिए यह रूट-स्तर पर () से पहले सभी फाइलों को ढूंढता है और किसी भी परीक्षण को शुरू करने से पहले निष्पादित करता है।

तो सुनिश्चित करें कि आपके पास एक समान पैटर्न है:

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

यह सलाह दी जाती है कि 'पहले से' में स्टब्स को इनिशियलाइज़ करें और 'बाद में' में उन्हें रिस्टोर करें। लेकिन अगर आप रोमांच महसूस कर रहे हैं, तो निम्नलिखित कार्य भी किए जाएंगे।

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

सैंडबॉक्स के साथ भी यह आपको त्रुटि दे सकता है। खासकर जब ईएस 6 कक्षाओं के समानांतर परीक्षण चलता है।

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

फिर भी आपको त्रुटि मिलेगी। आपको अलग-अलग तरीकों को ठोकर / जासूसी करनी होगी।

मैंने हमेशा के लिए यह जानने की कोशिश की कि क्या गलत था।

सिनोन-7.5.0


2

मैं जासूसों के साथ इसमें भाग गया। इस व्यवहार के साथ काम करने के लिए सिनॉन बहुत अनम्य है। मैंने एक हेल्पर फंक्शन बनाया जो किसी नए को स्थापित करने से पहले किसी भी मौजूदा जासूस को हटाने का प्रयास करता है। इस तरह से मुझे राज्य के पहले / बाद में किसी के बारे में चिंता करने की जरूरत नहीं है। एक समान दृष्टिकोण स्टब्स के लिए भी काम कर सकता है।

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

और परीक्षणों में स्टब्स बनाते समय इस फ़ंक्शन का उपयोग करें। यह 'सिनॉन एरर को रैप फंक्शन जो पहले से लिपटे है' एरर के लिए हल करेगा।

उदाहरण:

stub(Validator.prototype, 'canGeneratePayment').returns(Promise.resolve({ indent: dTruckIndent }));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.