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
austinbv.dll
sumber

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"
}));
keithjgrant.dll
sumber
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 [email protected], 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();
});
Myk Willis
sumber
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"
} 
anand
sumber
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');
}
Dimitris Zorbas
sumber
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

Sandeep Adi
sumber
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)
})
sethcall
sumber
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');
    }
);
sfuqua.dll
sumber
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(); 
    });
});
kavigun
sumber