Javascript 在 sinon.js 中存根和/或嘲笑一个类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12819242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stubbing and/or mocking a class in sinon.js?
提问by Industrial
I've created a database wrapper for my application, shown below. To test it, I obviously would like to replace the actual database library. I could create a new class that mocks the query
method and catch all input there, but using sinon.js
seems more appropriate, but how would I use it?
Is the mock
or stub
features of sinon.js
what I should be using?
我已经为我的应用程序创建了一个数据库包装器,如下所示。为了测试它,我显然想替换实际的数据库库。我可以创建一个新类来模拟该query
方法并在那里捕获所有输入,但使用sinon.js
似乎更合适,但我将如何使用它?
是mock
或stub
的特点sinon.js
是什么,我应该使用?
wrapper = (function() {
function wrapper() {}
wrapper.db = require("database");
wrapper.prototype.insertUser = function(doc) {
return this.db.query("INSERT INTO USERS...");
};
return wrapper;
})();
采纳答案by Cristiano Fontes
You can use both for that.
您可以同时使用两者。
Mockhave an expected ordered behavior that, if not followed correctly, is going to give you an error.
Mock有一个预期的有序行为,如果没有正确遵循,会给你一个错误。
A Stubis a similar to a mock, but without the order, so you can call your methods the way you want. In my experience you almost never need a mock.
一个存根是一个类似于模拟,但没有订单,所以你可以打电话给你的方法,你想要的方式。根据我的经验,您几乎不需要模拟。
Both of them will substitute your method for an empty method, or a closure if you pass one. It would be something like this:
它们都将替换您的方法为空方法,或者如果您传递一个闭包。它会是这样的:
stub = sinon.stub(wrapper , 'insertUser ', function () { return true; });
Then you add the expect behavior to check if it did happened.
然后你添加期望行为来检查它是否确实发生了。
I like to use Jasminewith Jasmine-Sinonfor checking the tests.
我喜欢使用Jasmine和Jasmine-Sinon来检查测试。
回答by Ricardo Stuven
First, I'd modify your class definition a bit (uppercase class name and fix db assignment):
首先,我会稍微修改您的类定义(大写类名并修复数据库分配):
var Wrapper = (function() {
function Wrapper() {
this.db = require("database");
}
Wrapper.prototype.insertUser = function(doc) {
return this.db.query("INSERT INTO USERS...");
};
return Wrapper;
})();
To stub the whole class:
要存根整个班级:
var WrapperStub = sinon.spy(function() {
return sinon.createStubInstance(Wrapper);
});
sinon.createStubInstance
will create an instance of Wrapper where every method is a stub. sinon.spy
will allow us to spy the class instantiation.
sinon.createStubInstance
将创建一个 Wrapper 实例,其中每个方法都是一个存根。sinon.spy
将允许我们监视类实例化。
So you could exercise it like this:
所以你可以像这样锻炼它:
// verify instantiation
var wrapper = new WrapperStub();
expect(WrapperStub).to.have.been.calledWithNew;
// verify method stub
wrapper.insertUser.returns('data');
expect(wrapper.insertUser()).to.equal('data');
expect(wrapper.insertUser).to.have.been.calledOnce;
(assertions use chaiand sinon-chai)
(断言使用chai和sinon-chai)
I said just "exercise it" because this code snippet is not an actual unit test. Instantiation and method calls will be made by your subject under test.
我说只是“执行它”,因为此代码片段不是实际的单元测试。实例化和方法调用将由您的被测对象进行。
Now, if you want to mock a dependency injected by require() –such as db = require('database')
in your example–, you could try a testing tool like either Jest(but not using sinon) or sinonquirewhich I created inspired by Jestbut to use it with sinon plus your favorite testing tool (mine is mocha). Internally, sinonquireuses the same technique shown above of combining sinon.spy
and sinon.createStubInstance
to stub a class.
现在,如果您想模拟由 require() 注入的依赖项(例如db = require('database')
在您的示例中),您可以尝试使用Jest(但不使用 sinon)或sinonquire 之类的测试工具,它是我受Jest启发而创建的,但将其与sinon 加上你最喜欢的测试工具(我的是mocha)。在内部,sinonquire使用与上面显示的相同的技术组合sinon.spy
和sinon.createStubInstance
存根类。