Limpando facilmente stubs sinon

134

Existe uma maneira de redefinir facilmente todas as zombarias e stubs de sinon spys que funcionarão corretamente com os blocos beforeEach de mocha.

Vejo que o sandbox é uma opção, mas não vejo como você pode usar um sandbox para esse

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
austinbv
fonte

Respostas:

304

O Sinon fornece essa funcionalidade através do uso de Sandboxes , que podem ser usadas de duas maneiras:

// 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"
}

ou

// 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"
}));
keithjgrant
fonte
6
@CamJackson Quando você tem testes assíncronos, precisa usar o primeiro método; caso contrário, o sinon limpa seus stubs antes que seu teste seja executado.
keithjgrant
3
Se você estiver usando sinon> 5.0, leia abaixo. Há agora um método muito mais fácil: stackoverflow.com/a/55251560/4464702
RAnders00
53

As respostas anteriores sugerem o uso sandboxespara fazer isso, mas de acordo com a documentação :

Desde [email protected], o objeto sinon é uma sandbox padrão.

Isso significa que limpar seus stubs / zombarias / espiões agora é tão fácil quanto:

var sinon = require('sinon');

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

afterEach(function () {
    sinon.restore();
});
Myk Willis
fonte
10
Esta é a melhor resposta para quem lê este depois de Abril de 2018.
Nick Cox
1
ainda neeter: afterEach (sinon.restore)
Benjam
Eu acho que isso é melhor porque caixas de areia explícitas criam complexidade desnecessária. Você realmente precisará de várias caixas de areia separadas com zombarias diferentes do mesmo objeto? Provavelmente não.
Gherman
13

Uma atualização para a resposta @keithjgrant.

A partir da versão v2.0.0 , o método sinon.test foi movido para um sinon-testmódulo separado . Para fazer os testes antigos passarem, você precisa configurar essa dependência extra em cada teste:

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

Como alternativa, você fica sem sinon-teste usa sandboxes :

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"
} 
anand
fonte
1
Ou você pode simplesmente realmente usar o pacote sinon-teste e continuar o seu código como antes :-D
oligofren
10

Você pode usar sinon.collection conforme ilustrado nesta postagem do blog (datada de maio de 2010) pelo autor da biblioteca sinon.

A API do sinon.collection mudou e uma maneira de usá-la é a seguinte:

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');
}
Dimitris Zorbas
fonte
6

restore()apenas restaura o comportamento da funcionalidade stubbed, mas não redefine o estado dos stubs. Você precisará encerrar seus testes sinon.teste usar this.stubou chamar individualmente reset()os stubs

Sandeep Adi
fonte
6

Se você deseja uma configuração que terá o sinon sempre se redefinirá para todos os testes:

em helper.js:

import sinon from 'sinon'

var sandbox;

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

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

Então, no seu teste:

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

Observe que ao usar o qunit em vez do mocha, é necessário envolvê-los em um módulo, por exemplo

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');
    }
);
sfuqua
fonte
3
o qunit 2 está mudando para beforeEache afterEach. Os métodos setupe teardownserão descontinuados.
precisa saber é o seguinte
0

Crie uma caixa de areia que funcionará como um recipiente de caixa preta para todos os seus espiões, tocos, zombarias e falsificações.

Tudo o que você precisa fazer é criar uma caixa de proteção no primeiro bloco de descrição, para que seja acessível em todos os casos de teste. E quando terminar todos os casos de teste, você deverá liberar os métodos originais e limpar os stubs usando o método sandbox.restore()no gancho afterEach, para que, em tempo de execução, libere recursos retidosafterEach caso de teste é aprovado ou falhou.

Aqui está um exemplo:

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