如何使用JsTestDriver测试jquery和ajax调用
How to test jquery and ajax calls using JsTestDriver?
我有一个用jQuery构建的动态页面。Html片段是从mustache模板加载的。这些模板是从一个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数据提供服务。下面的配置允许你把静态JSON测试数据(例如my_data.json)放在src/test/webapp/JSON中,把Mustache模板放在src/main/webapp/templates中。如果这对你的口味来说太maven了,你可以改变它来匹配你的源布局。
请注意,JsTestDriver使用/test/预先挂载到服务属性中指定的URI来服务资产,所以src/test/webapp/json/my_data. js . js . js . js . js . js . js . js . js。Json实际上是从http://localhost:9876/test/src/test/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数据解析模板并呈现预期的输出。
我找到了一种方法:模拟ajax调用。在http://tddjs.com/上,第12章中有一个示例,git存储库在这里: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 mock 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);
}
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- Javascript/jQuery中的并行Ajax调用
- 任何方式使AJAX调用Gmail API,而无需通过JS库
- node.js请求数据事件未在CORS ajax调用中触发
- 如何从ajax调用返回.wrap()元素
- Ajax调用在Firefox中不会自动响应
- AJAX调用中的非法调用
- 使用AJAX调用将GeoJSON数据拉入传单
- 在MVC 4中,对Controller的Ajax调用为空
- Jquery:对返回JSON数据的php脚本的Ajax调用
- 在ajax调用中阻止来自JS对象的函数
- 如何在MVC5中ajax调用的部分视图中引用外部javascript
- 页面加载后的Ajax调用
- 如何使用Ajax调用特定的控制器和操作来重定向用户
- curl和fileget_contents在ajax调用后不起作用
- 在任何AJAX调用之前触发一个javascript函数
- 无法在mvc视图中使用ajax调用获取操作返回的模型对象列表
- Ajax调用ERror Cross Origin REquest:在rails中自动完成大学列表
- ASP.NET MVC 3-在ajax调用后,重定向到新页面或生成页面刷新
- 点击功能没有'ajax调用动态元素(Backbone)后无法工作