Pulire facilmente i mozziconi di Sinon


135

C'è un modo per ripristinare facilmente tutti i mock e gli stub degli spys sinon che funzioneranno in modo pulito con i moka prima di ogni blocco.

Vedo sandboxing è un'opzione ma non vedo come è possibile utilizzare un sandbox per questo

beforeEach ->
  sinon.stub some, 'method'
  sinon.stub some, 'mother'

afterEach ->
  # I want to avoid these lines
  some.method.restore()
  some.other.restore()

it 'should call a some method and not other', ->
  some.method()
  assert.called some.method

Risposte:


304

Sinon fornisce questa funzionalità tramite l'uso di Sandbox , che possono essere utilizzati in due modi:

// manually create and restore the sandbox
var sandbox;
beforeEach(function () {
    sandbox = sinon.sandbox.create();
});

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

it('should restore all mocks stubs and spies between tests', function() {
    sandbox.stub(some, 'method'); // note the use of "sandbox"
}

o

// wrap your test function in sinon.test()
it("should automatically restore all mocks stubs and spies", sinon.test(function() {
    this.stub(some, 'method'); // note the use of "this"
}));

6
@CamJackson Quando hai i test asincroni, devi usare il primo metodo, altrimenti sinon pulisce i suoi stub prima che il test abbia terminato l'esecuzione.
keithjgrant,

3
Se stai usando sinon> 5.0 leggi sotto. C'è ora un metodo molto più semplice: stackoverflow.com/a/55251560/4464702
RAnders00

54

Le risposte precedenti suggeriscono di utilizzare sandboxesper ottenere questo risultato, ma secondo la documentazione :

Da sinon@5.0.0, l'oggetto sinon è un sandbox predefinito.

Ciò significa che ripulire i tuoi mozziconi / beffe / spie ora è facile come:

var sinon = require('sinon');

it('should do my bidding', function() {
    sinon.stub(some, 'method');
}

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

10
Questa è la risposta migliore per chiunque legga questo dopo aprile 2018.
Nick Cox,

1
anche neeter: afterEach (sinon.restore)
Benjam

Penso che sia meglio perché sandbox esplicite creano complessità inutili. Avrai davvero bisogno di più sandbox separate con diverse beffe dello stesso oggetto? Probabilmente no.
Gherman

13

Un aggiornamento alla risposta di @keithjgrant.

Dalla versione v2.0.0 in poi, il metodo sinon.test è stato spostato in un sinon-testmodulo separato . Per superare i vecchi test è necessario configurare questa dipendenza aggiuntiva in ciascun test:

var sinonTest = require('sinon-test');
sinon.test = sinonTest.configureTest(sinon);

In alternativa, fai a meno sinon-teste usi i sandbox :

var sandbox = sinon.sandbox.create();

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

it('should restore all mocks stubs and spies between tests', function() {
    sandbox.stub(some, 'method'); // note the use of "sandbox"
} 

1
Oppure puoi semplicemente usare il pacchetto sinon-test e continuare il tuo codice come prima :-D
oligofren

10

Puoi usare sinon.collection come illustrato in questo post del blog (datato maggio 2010) dall'autore della libreria sinon.

L'api sinon.collection è cambiato e un modo per usarlo è il seguente:

beforeEach(function () {
  fakes = sinon.collection;
});

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

it('should restore all mocks stubs and spies between tests', function() {
  stub = fakes.stub(window, 'someFunction');
}

6

restore()ripristina solo il comportamento della funzionalità stub ma non ripristina lo stato degli stub. Dovrai o avvolgere i test con sinon.teste utilizzare this.stubo chiamare individualmente reset()sugli stub


6

Se si desidera un'installazione che avrà sinon sempre ripristinarsi per tutti i test:

in helper.js:

import sinon from 'sinon'

var sandbox;

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

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

Quindi, nel tuo test:

it("some test", function() {
    this.sinon.stub(obj, 'hi').returns(null)
})

3

Si noti che quando si utilizza qunit invece di moka, è necessario avvolgerli in un modulo, ad es

module("module name"
{
    //For QUnit2 use
    beforeEach: function() {
    //For QUnit1 use
    setup: function () {
      fakes = sinon.collection;
    },

    //For QUnit2 use
    afterEach: function() {
    //For QUnit1 use
    teardown: function () {
      fakes.restore();
    }
});

test("should restore all mocks stubs and spies between tests", function() {
      stub = fakes.stub(window, 'someFunction');
    }
);

3
qunit 2 sta passando a beforeEache afterEach. I metodi setupe teardownsaranno deprecati.
Kevin Bullaughey,

0

Crea una sandbox che fungerà da contenitore di una scatola nera per tutte le tue spie, tronconi, beffe e falsi.

Tutto quello che devi fare è creare un sandbox nel primo blocco descrittivo in modo che sia accessibile in tutti i casi di test. E una volta sandbox.restore()terminati tutti i casi di test, è necessario rilasciare i metodi originali e ripulire gli stub utilizzando il metodo nell'hook afterEach in modo che durante l'esecuzione rilasci il afterEachcaso di test delle risorse trattenute venga superato o fallito.

Ecco un esempio:

 describe('MyController', () => {
    //Creates a new sandbox object
    const sandbox = sinon.createSandbox();
    let myControllerInstance: MyController;

    let loginStub: sinon.SinonStub;
    beforeEach(async () => {
        let config = {key: 'value'};
        myControllerInstance = new MyController(config);
        loginStub = sandbox.stub(ThirdPartyModule, 'login').resolves({success: true});
    });
    describe('MyControllerMethod1', () => {
        it('should run successfully', async () => {
            loginStub.withArgs({username: 'Test', password: 'Test'}).resolves();
            let ret = await myControllerInstance.run();
            expect(ret.status).to.eq('200');
            expect(loginStub.called).to.be.true;
        });
    });
    afterEach(async () => {
        //clean and release the original methods afterEach test case at runtime
        sandbox.restore(); 
    });
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.