![](/img/trans.png)
[英]Clojure: how can I bind a form to the global javascript namespace?
[英]How can I stub/mock a function in the javascript global namespace
我試圖在將日志寫入數據庫的測試期間存根/模擬/覆蓋函數調用。
function logit(msg) {
writeMessageToDb(msg);
}
function tryingToTestThisFunction(){
var error = processSomething();
if (error) {
logit(error);
}
}
我希望logit()
在測試期間簡單地打印到控制台......並且在logit()
函數中執行“ isTesting()
” if/else 塊不是一個選項。
這是否可能不包含一些額外的模擬框架。 我目前正在使用JsTestDriver
進行單元測試,還沒有機會評估任何模擬框架。 目前一個理想的解決方案是在沒有其他框架的情況下處理這個問題。
我使用 Jasmine 和 Sinon.js(使用 Coffeescript),下面是我如何將confirm()方法存根,例如,只返回 true。
beforeEach ->
@confirmStub = sinon.stub(window, 'confirm')
@confirmStub.returns(true)
afterEach ->
@confirmStub.restore()
在 javascript 中,最新的定義是流行的。
所以只需在第一個定義之后重新定義 logit 方法。
function logit(msg) {
console.log(msg);
}
我一直在研究完全相同的問題。 開發人員給了我一個 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>
Javascript 不僅是運行時鏈接的,也是最后一個詞 wins鏈接的。 這意味着您可以在測試中使用您想要的行為重新聲明該方法(因為您的測試具有最后一個詞):
function yourTest(){
oldImpl = logit; // An even better approach is to do this in 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. An even better approach is to do this in a teardown.
}
你能覆蓋window對象上的方法嗎? 在 Chrome 控制台中,這有效
function test() {console.log('test')};
window.test();
只需覆蓋 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))
}
}
}());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.