Dọn dẹp cuống sinon dễ dàng


134

Có cách nào để dễ dàng thiết lập lại tất cả các mô phỏng và cuống sinon sẽ hoạt động sạch sẽ với các khối trước của mocha không.

Tôi thấy hộp cát là một tùy chọn nhưng tôi không thấy cách bạn có thể sử dụng hộp cát cho việc này

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

Câu trả lời:


304

Sinon cung cấp chức năng này thông qua việc sử dụng Sandbox , có thể được sử dụng theo một số cách:

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

hoặc là

// 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 Khi bạn có các bài kiểm tra async, bạn cần sử dụng phương thức đầu tiên, nếu không sinon sẽ dọn sạch các sơ khai của nó trước khi bài kiểm tra của bạn kết thúc.
keithjgrant

3
Nếu bạn đang sử dụng sinon> 5.0 hãy đọc phần bên dưới. Bây giờ có một phương pháp dễ dàng hơn nhiều: stackoverflow.com/a/55251560/4464702
RAnders00

53

Các câu trả lời trước đề nghị sử dụng sandboxesđể thực hiện điều này, nhưng theo tài liệu :

Vì sinon@5.0.0, đối tượng sinon là một hộp cát mặc định.

Điều đó có nghĩa là việc dọn dẹp sơ khai / giả / gián điệp của bạn giờ đây dễ dàng như:

var sinon = require('sinon');

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

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

10
Đây là câu trả lời tốt nhất cho bất cứ ai đọc nó sau tháng 4 năm 2018.
Nick Cox

1
thậm chí neeter: afterEach (sinon.restore)
Stewam

Tôi nghĩ rằng điều này là tốt hơn bởi vì các hộp cát rõ ràng tạo ra sự phức tạp không cần thiết. Bạn có thực sự cần một vài hộp cát riêng biệt với các giả khác nhau của cùng một đối tượng không? Chắc là không.
Gherman

13

Một bản cập nhật cho câu trả lời @keithjgrant.

Từ phiên bản v2.0.0 trở đi, phương thức sinon.test đã được chuyển sang một sinon-testmô-đun riêng . Để vượt qua các bài kiểm tra cũ, bạn cần định cấu hình phụ thuộc bổ sung này trong mỗi bài kiểm tra:

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

Ngoài ra, bạn làm mà không có sinon-testvà sử dụng hộp cát :

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
Hoặc bạn thực sự có thể sử dụng gói kiểm tra sinon và tiếp tục mã của mình như trước :-D
oligofren

10

Bạn có thể sử dụng sinon.collection như minh họa trong này bài đăng trên blog (ngày tháng 5 năm 2010) bởi tác giả của thư viện sinon.

Api sinon.collection đã thay đổi và cách sử dụng nó là như sau:

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()chỉ khôi phục hoạt động của chức năng gốc nhưng nó không thiết lập lại trạng thái của các sơ khai. Bạn sẽ phải bọc các bài kiểm tra của mình sinon.testvà sử dụng this.stubhoặc gọi riêng cho reset()các cuống


6

Nếu bạn muốn thiết lập có sinon, hãy luôn tự thiết lập lại cho tất cả các thử nghiệm:

trong helper.js:

import sinon from 'sinon'

var sandbox;

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

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

Sau đó, trong bài kiểm tra của bạn:

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

3

Lưu ý rằng khi sử dụng qunit thay vì mocha, bạn cần bọc chúng trong một mô-đun, ví dụ:

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 đang chuyển sang beforeEachafterEach. Các setupteardownphương pháp sẽ không được chấp nhận.
Kevin Bullaughey

0

Tạo một hộp cát sẽ hoạt động như một hộp chứa màu đen cho tất cả các gián điệp, cuống, giả và giả của bạn.

Tất cả bạn phải làm là tạo một hộp cát trong khối mô tả đầu tiên để nó có thể truy cập được trong tất cả các trường hợp thử nghiệm. Và một khi bạn đã hoàn thành tất cả các trường hợp thử nghiệm, bạn nên giải phóng các phương thức ban đầu và dọn sạch các sơ khai bằng cách sử dụng phương thức sandbox.restore()trong hook afterEach để trong thời gian chạy, nó giải phóng các tài nguyên bị giữafterEach trường hợp kiểm tra bị vượt qua hoặc thất bại.

Đây là một ví dụ:

 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(); 
    });
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.