Легкая очистка пазухи


135

Есть ли способ легко сбросить все макеты и заглушки, которые будут работать чисто с блоками mocha beforeEach.

Я вижу, что песочница - это вариант, но я не вижу, как вы можете использовать песочницу для этого

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 предоставляет эту функциональность с помощью песочниц , которые можно использовать несколькими способами:

// 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 Когда у вас есть асинхронные тесты, вам нужно использовать первый метод, иначе sinon очищает свои заглушки до того, как ваш тест завершится.
keithjgrant

3
Если вы используете sinon> 5.0, читайте ниже. Теперь есть гораздо более простой способ: stackoverflow.com/a/55251560/4464702
RAnders00

54

Предыдущие ответы предлагают использовать 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 года.
Ник Кокс

1
еще позже: afterEach (sinon.restore)
Бенджам

Я думаю, что это лучше, потому что явные песочницы создают ненужную сложность. Вам действительно понадобятся несколько отдельных песочниц с разными макетами одного и того же объекта? Возможно нет.
Герман

13

Обновление @keithjgrant ответа.

Начиная с версии 2.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-test и продолжить свой код, как и раньше :-D
oligofren

10

Вы можете использовать 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 вместо mocha вам нужно обернуть их в модуль, например

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и afterEach. setupИ teardownметоды будут устаревшими.
Кевин Буллауги

0

Создайте песочницу, которая будет действовать как контейнер черного ящика для всех ваших шпионов, пней, издевательств и подделок.

Все, что вам нужно сделать, это создать песочницу в самом первом блоке описаний, чтобы она была доступна во всех тестовых примерах. И как только вы закончите со всеми тестовыми примерами, вы должны освободить исходные методы и очистить заглушки, используя метод sandbox.restore()в ловушке afterEach, чтобы во время выполнения он освободил задержанные ресурсы. 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(); 
    });
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.