155

有没有一种方法可以轻松地重置所有可以与 mocha 的 beforeEach 块一起干净地工作的 sinon spys 模拟和存根。

我看到沙盒是一种选择,但我看不出如何为此使用沙盒

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
4

9 回答 9

318

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"
}));
于 2012-12-26T13:55:40.393 回答
100

以前的答案建议使用sandboxes来完成此操作,但根据文档

从 sinon@5.0.0 开始, sinon 对象是默认沙箱。

这意味着清理你的存根/模拟/间谍现在很容易:

var sinon = require('sinon');

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

afterEach(function () {
    sinon.restore();
});
于 2019-03-19T23:45:47.753 回答
14

@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"
} 
于 2017-04-19T03:30:13.833 回答
9

您可以使用 sinon 库的作者在这篇博文(日期为 2010 年 5 月)中说明的 sinon.collection。

sinon.collection api 已更改,使用方法如下:

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');
}
于 2013-07-11T21:36:46.323 回答
6

restore()只是恢复存根功能的行为,但不会重置存根的状态。您必须使用存根包装测试sinon.test并使用this.stub或单独调用reset()存根

于 2016-06-16T16:22:02.613 回答
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)
})
于 2016-07-18T12:41:47.857 回答
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');
    }
);
于 2014-04-18T14:54:07.847 回答
2

创建一个沙盒,它将充当所有间谍、存根、模拟和伪造品的黑盒容器。

您所要做的就是在第一个描述块中创建一个沙箱,以便在所有测试用例中都可以访问它。一旦你完成了所有的测试用例,你应该释放原始方法并使用 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(); 
    });
});
于 2020-04-20T09:43:04.397 回答
0

下面将重置所有存根和嵌套存根。

sinon.reset();

或者你做 NameOfFunctiontionYouWantToReset.resetHistory();

addingStub.resetHistory();

于 2021-05-11T15:09:58.843 回答