Cleaning up sinon stubs easily

2019-01-16 06:02发布

Is there a way to easily reset all sinon spys mocks and stubs that will work cleanly with mocha's beforeEach blocks.

I see sandboxing is an option but I do not see how you can use a sandbox for this

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

6条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-16 06:51

Sinon provides this functionality through the use of Sandboxes, which can be used a couple ways:

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

or

// 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"
}));
查看更多
一纸荒年 Trace。
3楼-- · 2019-01-16 06:51

Note that when using qunit instead of mocha, you need to wrap these in a module, e.g.

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');
    }
);
查看更多
Explosion°爆炸
4楼-- · 2019-01-16 06:52

You may use sinon.collection as illustrated in this blog post (dated May 2010) by the author of the sinon library.

The sinon.collection api has changed and a way to use it is the following:

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');
}
查看更多
不美不萌又怎样
5楼-- · 2019-01-16 06:53

An update to @keithjgrant answer.

From version v2.0.0 onwards, the sinon.test method has been moved to a separate sinon-test module. To make the old tests pass you need to configure this extra dependency in each test:

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

Alternatively, you do without sinon-test and use sandboxes:

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"
} 
查看更多
男人必须洒脱
6楼-- · 2019-01-16 06:55

restore() just restores the behavior of the stubbed functionality but it doesn't reset the state of the stubs. You'll have to either wrap your tests with sinon.test and use this.stub or individually call reset() on the stubs

查看更多
The star\"
7楼-- · 2019-01-16 06:58

If you want a setup that will have sinon always reset itself for all tests:

in helper.js:

import sinon from 'sinon'

var sandbox;

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

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

Then, in your test:

it("some test", function() {
    this.sinon.stub(obj, 'hi').returns(null)
})
查看更多
登录 后发表回答