Membersihkan rintisan sinon dengan mudah


137

Apakah ada cara untuk dengan mudah mengatur ulang semua ejekan dan stub sinon mata-mata yang akan bekerja dengan bersih dengan blok beforeEach moka.

Saya melihat sandboxing adalah opsi tetapi saya tidak melihat bagaimana Anda dapat menggunakan kotak pasir untuk ini

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

Jawaban:


304

Sinon menyediakan fungsionalitas ini melalui penggunaan Sandbox , yang dapat digunakan dengan beberapa cara:

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

atau

// 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 Ketika Anda memiliki tes async, Anda perlu menggunakan metode pertama, jika tidak sinon membersihkan rintisannya sebelum tes Anda selesai dijalankan.
keithjgrant

3
Jika Anda menggunakan sinon> 5.0 baca di bawah. Sekarang ada metode yang jauh lebih mudah: stackoverflow.com/a/55251560/4464702
RAnders00

62

Jawaban sebelumnya menyarankan penggunaan sandboxesuntuk mencapai ini, tetapi menurut dokumentasi :

Sejak sinon@5.0.0, objek sinon adalah sandbox default.

Artinya, membersihkan rintisan / tiruan / mata-mata Anda sekarang semudah:

var sinon = require('sinon');

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

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

10
Ini adalah jawaban terbaik bagi siapa pun yang membaca ini setelah April 2018.
Nick Cox

1
bahkan lebih rapi: afterEach (sinon.restore)
Benjam

Saya pikir ini lebih baik karena kotak pasir eksplisit menciptakan kerumitan yang tidak perlu. Apakah Anda benar-benar akan membutuhkan beberapa kotak pasir terpisah dengan tiruan berbeda dari objek yang sama? Mungkin tidak.
Gherman

13

Pembaruan untuk jawaban @keithjgrant.

Dari versi v2.0.0 dan seterusnya, metode sinon.test telah dipindahkan ke modul terpisahsinon-test . Agar pengujian lama berhasil, Anda perlu mengonfigurasi dependensi tambahan ini di setiap pengujian:

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

Atau, Anda melakukannya tanpa sinon-testdan menggunakan kotak pasir :

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
Atau Anda bisa menggunakan paket sinon-test dan melanjutkan kode Anda seperti sebelumnya :-D
oligofren

9

Anda dapat menggunakan sinon.collection seperti yang diilustrasikan dalam posting blog ini (tertanggal Mei 2010) oleh penulis perpustakaan sinon.

Api sinon.collection telah berubah dan cara menggunakannya adalah sebagai berikut:

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()hanya memulihkan perilaku fungsionalitas yang dipotong tetapi tidak mengatur ulang status rintisan. Anda harus membungkus pengujian Anda dengan sinon.testdan menggunakan this.stubatau secara individu memanggil reset()stub


6

Jika Anda menginginkan pengaturan yang akan membuat sinon selalu mengatur ulang dirinya sendiri untuk semua tes:

di helper.js:

import sinon from 'sinon'

var sandbox;

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

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

Kemudian, dalam pengujian Anda:

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

3

Perhatikan bahwa saat menggunakan qunit alih-alih mocha, Anda perlu menggabungkannya dalam sebuah modul, mis

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 beralih ke beforeEachdan afterEach. Metode setupdan tidak teardownakan digunakan lagi.
Kevin Bullaughey

0

Buat kotak pasir yang akan bertindak sebagai wadah kotak hitam untuk semua mata-mata, rintisan, pengolok, dan pemalsuan Anda.

Yang harus Anda lakukan adalah membuat kotak pasir di blok mendeskripsikan yang pertama sehingga dapat diakses di semua kasus pengujian. Dan setelah Anda selesai dengan semua kasus pengujian, Anda harus merilis metode asli dan membersihkan stub menggunakan metode sandbox.restore()di hook afterEach sehingga pada waktu proses rilis yang tertahan afterEachkasus pengujian resource dilewatkan atau gagal.

Berikut ini contohnya:

 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(); 
    });
});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.