轻松清理 sinon 存根
Posted
技术标签:
【中文标题】轻松清理 sinon 存根【英文标题】:Cleaning up sinon stubs easily 【发布时间】:2012-07-18 04:11:02 【问题描述】:有没有一种方法可以轻松地重置所有可以与 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
【问题讨论】:
【参考方案1】:下面将重置所有存根和嵌套存根。
sinon.reset();
或者你做
NameOfFunctiontionYouWantToReset.resetHistory();
喜欢
addingStub.resetHistory();
【讨论】:
【参考方案2】:创建一个沙盒,它将充当所有间谍、存根、模拟和伪造品的黑盒容器。
您所要做的就是在第一个描述块中创建一个沙箱,以便在所有测试用例中都可以访问它。一旦你完成了所有的测试用例,你应该释放原始方法并使用 afterEach 钩子中的方法sandbox.restore()
清理存根,以便在运行时它释放持有的资源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();
);
);
【讨论】:
【参考方案3】:以前的答案建议使用sandboxes
来完成此操作,但根据the documentation:
从 sinon@5.0.0 开始,sinon 对象是默认的沙箱。
这意味着清理你的存根/模拟/间谍现在很容易:
var sinon = require('sinon');
it('should do my bidding', function()
sinon.stub(some, 'method');
afterEach(function ()
sinon.restore();
);
【讨论】:
这是 2018 年 4 月之后阅读本文的任何人的最佳答案。 甚至更奇怪:afterEach(sinon.restore) 我认为这更好,因为显式沙箱会产生不必要的复杂性。你真的需要几个独立的沙箱,对同一个对象有不同的模拟吗?可能不会。 是不是说sinon.stub(some, 'method'); 没有区别和 const sandbox = sinon.createSandbox(); sandbox.stub(some, 'method'); ? 当我在 afterEach 钩子中使用sinon.restore()
时收到此消息 (sinon.restore is deprecated and will be removed from the public API in a future version of sinon.
)【参考方案4】:
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"
));
【讨论】:
@CamJackson 当你有异步测试时,你需要使用第一种方法,否则 sinon 在你的测试执行完成之前清理它的存根。 如果您使用的是 sinon >5.0,请阅读下文。现在有一个更简单的方法:***.com/a/55251560/4464702【参考方案5】:@keithjgrant 答案的更新。
从 v2.0.0 版本开始,sinon.test 方法已移至a separate sinon-test
module。要使旧测试通过,您需要在每个测试中配置这个额外的依赖项:
var sinonTest = require('sinon-test');
sinon.test = sinonTest.configureTest(sinon);
或者,您可以不使用 sinon-test
并使用 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"
【讨论】:
或者你可以实际使用 sinon-test 包并像以前一样继续你的代码:-D【参考方案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)
)
【讨论】:
【参考方案7】:restore()
只是恢复存根功能的行为,但不会重置存根的状态。您必须使用 sinon.test
包装您的测试并使用 this.stub
或在存根上单独调用 reset()
【讨论】:
【参考方案8】:请注意,当使用 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');
);
【讨论】:
qunit 2 正在切换到beforeEach
和afterEach
。 setup
和 teardown
方法将被弃用。【参考方案9】:
您可以使用 sinon 库作者在 this 博客文章(日期为 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');
【讨论】:
以上是关于轻松清理 sinon 存根的主要内容,如果未能解决你的问题,请参考以下文章