我正在尝试在测试期间存根/模拟/覆盖函数调用,这会将日志写入数据库。
function logit(msg) {
writeMessageToDb(msg);
}
function tryingToTestThisFunction(){
var error = processSomething();
if (error) {
logit(error);
}
}
我希望logit()
在测试期间简单地打印到控制台...并且在isTesting()
函数中执行“logit()
”if / else块不是一个选项。
这可能不包括一些额外的模拟框架。我目前正在使用JsTestDriver
进行单元测试,并且没有机会评估任何模拟框架。目前理想的解决方案是在没有其他框架的情况下处理这个问题。
答案 0 :(得分:7)
我使用Jasmine和Sinon.js(使用Coffeescript),这是我如何将confirm()方法存根,例如,只返回true。
beforeEach ->
@confirmStub = sinon.stub(window, 'confirm')
@confirmStub.returns(true)
afterEach ->
@confirmStub.restore()
答案 1 :(得分:3)
在javascript中,最新的定义是流行的。
所以只需在第一个定义之后重新定义logit方法。
function logit(msg) {
console.log(msg);
}
答案 2 :(得分:1)
你可以覆盖窗口对象上的方法吗?在Chrome控制台中,这可以正常工作
function test() {console.log('test')};
window.test();
答案 3 :(得分:1)
只需覆盖logit函数,这可以在logit定义之后的任何时间调用。
(function(){
//keep handle to original logit method.
var ol = logit;
//shorter lookup path for slice
var s = Array.prototype.slice;
//logit override
logit = function() {
//if in testing
if (typeof IsTesting == "function" && !!IsTesting()) {
//log the arguments
console.log.apply(console, s.call(arguments));
} else {
//otherwise, call the original function.
ol.apply(this, s.call(arguments))
}
}
}());
答案 4 :(得分:1)
我一直在研究完全相同的问题。开发人员给了我一个HTML5应用程序来测试,所以我当然不能改变他们的代码进行测试。我决定使用qunit和sinon以及sinon-qunit。
对于像我这样的新手到JavaScript单元测试,我对网络上的sinon文档和各种示例感到疯狂,因为大部分内容似乎都是未提及的隐含环境。下面的代码是一个完整的页面,所以我希望不会有任何混淆。
我必须调用的函数是caller()
,我无法对stubme()
做任何事情,因为它在开发人员的代码中。但是,我可以在我的测试代码中添加sinonstub()
。但是如何让它与sinon一起工作? sinon文档确实让我困惑了一段时间,但下面是简单的解决方案。 stub4stubme对象可用于控制存根操作,还可以获取存根调用发生的信息。
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="qunit-1.12.0.css" type="text/css" media="screen" />
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="sinon-1.7.3.js"></script>
<script src="qunit-1.12.0.js"></script>
<script src="sinon-qunit-0.8.0.js"></script>
<script>
// Dev code in another file
function stubme() {
return "stubme";
}
function caller() {
return "caller " + stubme();
}
// End of dev code
var sinonstub = function () {
return "u haz bin stubbed";
};
test("Stubbing global environments", function () {
equal(caller(), "caller stubme");
var stub4stubme = this.stub(window, "stubme", sinonstub);
equal(caller(), "caller u haz bin stubbed");
ok(stubme.called);
});
</script>
</body>
</html>
答案 5 :(得分:0)
因为在Javascript中不仅链接了运行时,而且最后一个单词获胜已链接,只需使用您在测试中所需的行为重新声明该方法:
function yourTest(){
oldImpl = logit; // better to use a setup.
logit = function(msg){ Console.log.apply(console, s.call(arguments));};
// do you assertions: assert.... yada.
logit = oldImpl; // Do this to keep your test isolated from the others you'll be executing in this test run. Better to use a tear down.
}