[英]How to test jquery and ajax calls using JsTestDriver?
我有一個用 jQuery 構建的動態頁面。 Html 件從小胡子模板加載。 這些模板是從 url 下載的,我想對整個 html 結構進行單元測試:
JsTestDriver 測試是:
AppTest = TestCase("AppTest")
AppTest.prototype.test = function() {
var actualHtml = "";
getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) {
actualHtml = html;
});
assertEquals("expected html", actualHtml);
};
和代碼:
function getHtml(json, resultFunc) {
jQuery.ajax({
url: "url/to/mustache/template",
success: function(view) {
resultFunc(mergeArticleModelAndView(json, view));
},
error: function(jqXHR, textStatus, errorThrown) {
resultFunc(textStatus + " errorThrown: " + errorThrown);
},
dataType: 'text',
async: false
});
}
然后我啟動測試,結果是:
$ java -jar JsTestDriver-1.3.2.jar --port 9876 --browser /usr/bin/firefox --tests all
F
Total 1 tests (Passed: 0; Fails: 1; Errors: 0) (8,00 ms)
Firefox 5.0 Linux: Run 1 tests (Passed: 0; Fails: 1; Errors 0) (8,00 ms)
AppTest.test failed (8,00 ms): AssertError: expected "expected html" but was "error errorThrown: [Exception... \"Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)\" nsresult: \"0x80004005 (NS_ERROR_FAILURE)\" location: \"JS frame :: http://localhost:9876/test/main/js/jquery.min.js :: <TOP_LEVEL> :: line 16\" data: no]"
()@http://localhost:9876/test/test/js/app_test.js:25
所以錯誤回調已被調用,我不明白為什么它會與 JsTestDriver 中斷,並且代碼在使用瀏覽器手動調用應用程序時有效
最后一件事,jsTestDriver.conf:
server: http://localhost:9876
load:
- test/js/app_test.js
- main/js/jquery.min.js
- main/js/jquery.mustache.js
- main/js/app.js
謝謝你的建議。 更一般地說,您使用哪些單元測試框架進行 javascript 以及使用 DOM 和 jQuery 的命令行測試?
另一種方法是讓 JsTestDriver 為您的模板和一些測試 JSON 數據提供服務。 下面的配置允許您將 static JSON 測試數據(例如 my_data.json)放在 src/test/webapp/json 中,並將 Mustache 模板放在 src/main/webapp/templates 中。 如果這太 Maven 不適合您的口味,您可以更改它以匹配您的源布局。
請注意,JsTestDriver 使用 /test/ 預置在 serve 屬性中指定的 URI 來提供資產,因此 src/test/webapp/json/my_data.json 實際上是從 http:/ /localhost:9876/test/src/ 提供的測試/webapp/json/my_data.json。
server: http://localhost:9876
serve:
- src/main/webapp/templates/*.html
- src/test/webapp/json/*.json
load:
- src/main/webapp/js/*.js
- src/main/webapp/js/libs/*.js
test:
- src/test/webapp/js/*.js
然后,在測試用例中,您可以輕松加載模板和 JSON 數據。
testLoadTemplateAndData : function () {
// Variables
var onComplete, template, data, expected, actual, templateLoaded, dataLoaded;
dataLoaded = false;
templateLoaded = false;
expected = "<h2>Your expected markup</h2>";
// Completion action
onComplete = function () {
if (dataLoaded && templateLoaded) {
// Render the template and data
actual = Mustache.to_html(template, data);
// Compare with expected
assertEquals('Markup should match', expected, actual);
}
};
// Load data with jQuery
$.ajax({
url : '/test/src/test/webapp/json/demo.json',
success :
function (result) {
data = result;
dataLoaded = true;
},
error :
function () {
fail("Data did not load.");
},
complete :
function () {
onComplete();
}
}
);
// Load the template with jQuery
$.get('/test/src/main/webapp/templates/demo.html',
function(result) {
template = result;
templateLoaded = true;
}
)
.error(function() { fail("Template did not load."); })
.complete(function() {
onComplete();
});
}
當 jQuery 回調完成時,Mustache 應該使用 JSON 數據解析模板並呈現預期的 output。
我找到了一種方法:模擬 ajax 調用。 On http://tddjs.com/ there is an example to do so in chapter 12, and the git repository is here: http://tddjs.com/code/12-abstracting-browser-differences-ajax.git
所以測試代碼是:
TestCase("AppTest", {
setUp: function() {
tddjs.isLocal = stubFn(true);
var ajax = tddjs.ajax;
this.xhr = Object.create(fakeXMLHttpRequest);
this.xhr.send=function () {
this.readyState = 4;
this.onreadystatechange();
};
this.xhr.responseText="<expected data>";
ajax.create = stubFn(this.xhr);
},
"test article html ok": function () {
var actualHtml = "";
getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) {
actualHtml = html;
});
assertEquals("<expected html>", actualHtml);
}
});
和生產代碼:
function getHtml(model, resultFunc) {
tddjs.ajax.get("http://url/to/template", {
success: function (xhr) {
resultFunc(mergeArticleModelAndView(model, xhr.responseText));
}
});
}
閱讀 jQuery 代碼后,我認為可以模擬 jQuery ajax 請求。 參見 jquery 1.5 模擬 ajax
是的,可以用 jquery 做同樣的事情:
測試代碼(只是測試的設置是一樣的):
TestCase("AppTest", {
setUp: function() {
this.xhr = Object.create(fakeXMLHttpRequest);
this.xhr.send=function () {
this.readyState = 4;
};
this.xhr.getAllResponseHeaders=stubFn({});
this.xhr.responseText="<expected data>";
jQuery.ajaxSettings.isLocal=stubFn(true);
jQuery.ajaxSettings.xhr=stubFn(this.xhr);
},
// same test method
和生產代碼:
function getHtml(model, resultFunc) {
$.get("/url/to/template", function(view) {
resultFunc(mergeArticleModelAndView(model, view));
});
}
這就是我們選擇的解決方案。
使用 sinon.js 就更簡單了:
TestCase("AppTest", {
setUp: function() {
this.server = sinon.fakeServer.create();
},
tearDown: function() {
this.server.restore();
},
"test article html ok": function () {
this.server.respondWith("mustache template");
this.server.respond();
var actualHtml = "";
getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) {
actualHtml = html;
});
assertEquals("<expected html>", actualHtml);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.