ทำความสะอาดต้นขั้ว Sinon ได้อย่างง่ายดาย


137

มีวิธีในการรีเซ็ตสไปซ์ไซนอนม็อกและต้นขั้วทั้งหมดอย่างง่ายดายซึ่งจะทำงานได้อย่างหมดจดกับมอคค่าก่อนหน้าแต่ละบล็อก

ฉันเห็นว่าแซนด์บ็อกซ์เป็นตัวเลือก แต่ฉันไม่เห็นว่าคุณจะใช้แซนด์บ็อกซ์ได้อย่างไร

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

คำตอบ:


304

Sinon ให้ฟังก์ชันนี้ผ่านการใช้Sandboxesซึ่งสามารถใช้ได้สองวิธี:

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

หรือ

// 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 เมื่อคุณได้รับการทดสอบแบบ async คุณต้องใช้วิธีแรกมิฉะนั้น sinon จะทำความสะอาดต้นขั้วก่อนที่การทดสอบของคุณจะเสร็จสิ้น
keithjgrant

3
หากคุณใช้ sinon> 5.0 โปรดอ่านด้านล่าง ตอนนี้มีวิธีที่ง่ายกว่ามาก: stackoverflow.com/a/55251560/4464702
RAnders00

62

คำตอบก่อนหน้านี้แนะนำให้ใช้sandboxesเพื่อทำสิ่งนี้ให้สำเร็จ แต่ตามเอกสาร :

เนื่องจาก sinon@5.0.0 อ็อบเจ็กต์ sinon จึงเป็นแซนด์บ็อกซ์เริ่มต้น

นั่นหมายความว่าตอนนี้การทำความสะอาดต้นขั้ว / ม็อก / สายลับของคุณนั้นง่ายพอ ๆ กับ:

var sinon = require('sinon');

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

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

10
นี่คือคำตอบที่ดีที่สุดสำหรับทุกคนที่อ่านเนื้อหานี้หลังเดือนเมษายน 2018
Nick Cox

1
แม้ neeter: afterEach (sinon.restore)
เบญจม

ฉันคิดว่าสิ่งนี้ดีกว่าเพราะแซนด์บ็อกซ์ที่ชัดเจนสร้างความซับซ้อนโดยไม่จำเป็น คุณจำเป็นต้องใช้แซนด์บ็อกซ์หลาย ๆ อันแยกจากกันจริง ๆ หรือไม่? อาจจะไม่.
Gherman

13

การอัปเดตคำตอบของ @keithjgrant

จากรุ่นv2.0.0เป็นต้นไปsinon.testวิธีการได้ถูกย้ายไปแยกsinon-testโมดูล ในการทำให้การทดสอบเก่าผ่านไปคุณต้องกำหนดค่าการอ้างอิงเพิ่มเติมนี้ในการทดสอบแต่ละครั้ง:

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

หรือคุณทำโดยไม่มีsinon-testและใช้แซนด์บ็อกซ์ :

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
หรือคุณสามารถใช้แพคเกจทดสอบ sinon และดำเนินการต่อรหัสของคุณเหมือนเดิม :-D
oligofren

9

คุณสามารถใช้ sinon.collection ตามภาพประกอบในบล็อกโพสต์นี้ (ลงวันที่พฤษภาคม 2010) โดยผู้เขียนห้องสมุด sinon

api sinon.collection มีการเปลี่ยนแปลงและวิธีการใช้งานมีดังต่อไปนี้:

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()เพียงแค่เรียกคืนลักษณะการทำงานของฟังก์ชันที่ถูกตรึง แต่จะไม่รีเซ็ตสถานะของต้นขั้ว คุณจะต้องปิดการทดสอบของคุณด้วยsinon.testและใช้this.stubหรือโทรหาreset()ต้นขั้วเป็นรายบุคคล


6

หากคุณต้องการตั้งค่าที่จะให้ sinon รีเซ็ตตัวเองเสมอสำหรับการทดสอบทั้งหมด:

ใน helper.js:

import sinon from 'sinon'

var sandbox;

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

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

จากนั้นในการทดสอบของคุณ:

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

3

โปรดทราบว่าเมื่อใช้ qunit แทนมอคค่าคุณต้องห่อสิ่งเหล่านี้ไว้ในโมดูลเช่น

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 จะเปลี่ยนไปใช้และbeforeEach และวิธีการจะเลิก afterEachsetupteardown
Kevin Bullaughey

0

สร้างแซนด์บ็อกซ์ซึ่งจะทำหน้าที่เป็นที่เก็บกล่องดำสำหรับสายลับต้นขั้วล้อเลียนและของปลอมทั้งหมดของคุณ

สิ่งที่คุณต้องทำคือสร้างแซนด์บ็อกซ์ในบล็อกแรกอธิบายเพื่อให้สามารถเข้าถึงได้ตลอดทุกกรณีการทดสอบ และเมื่อคุณดำเนินการกับกรณีทดสอบทั้งหมดเสร็จแล้วคุณควรปล่อยเมธอดดั้งเดิมและล้างสตับโดยใช้เมธอด sandbox.restore()ใน afterEach hook เพื่อที่รันไทม์ที่ปล่อยafterEachกรณีทดสอบรีซอร์สที่ค้างไว้จะถูกส่งผ่านหรือล้มเหลว

นี่คือตัวอย่าง:

 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(); 
    });
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.