如何使用 Mocha 编写 Ajax 请求的单元测试
介绍
测试驱动开发 (TDD) 涉及在实际编码之前编写测试。与 TDD 配合使用的常见测试堆栈包括 Mocha、Chai 和 Sinon。
简而言之,Mocha 是一个在Node.js和浏览器上运行的 JavaScript 测试框架。它使用户能够轻松执行异步测试。Chai 是一个 BDD/TDD 断言库,也可以在Node上运行,并且浏览器可以轻松与任何 JavaScript 测试框架配对。Sinon 为 JavaScript 提供独立的测试间谍、存根和模拟,并且可以与任何单元测试框架配合使用。
很自然地,人们会认为 Ajax 请求并不总是按计划进行,因为您既无法确保连接的稳定性,也无法验证服务器本身的功能。然而,Ajax 请求通常会将用户数据来回传送到服务器。此类数据的完整性至关重要,您必须小心处理。然而,测试这些请求是一个关键而敏感的问题。这是一个异步过程;因此,理想的单元测试必须是隔离的。但是,当您的代码与服务器交互时,您如何隔离它呢?
本指南介绍如何高效、有效地测试 Ajax 请求。
设置
在深入研究之前,请准备好环境并设置测试所需的工具。
首先创建一个目录来存放必要的文件。接下来,使用npm install mocha chai sinon安装 Mocha、Chai 和 Sinon。
测试运行器
您可以直接在浏览器中运行这些测试。它们在基于控制台的运行器中的表现类似,因此如果您愿意,请不要犹豫使用它们。
检查下面的测试运行器。您可以在此处以名称 testrunner.html 下载它。
<!DOCTYPE html>
<html>
<head>
<title>Mocha Test</title>
<link rel="stylesheet" href="node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="node_modules/mocha/mocha.js"></script>
<script src="node_modules/sinon/pkg/sinon-1.12.2.js"></script>
<script src="node_modules/chai/chai.js"></script>
<script>mocha.setup('bdd')</script>
<script src="myapi.js"></script>
<script src="test.js"></script>
<script>
mocha.run();
</script>
</body>
</html>
由于您使用npm安装了mocha.css、mocha.js、sinon-1.12.2.js和chai.js,它们现在位于node_modules目录中。如果您安装的版本与本指南中的版本不匹配,您可能需要修改 Sinon 的文件名以匹配您安装的版本。
在本指南中,myapi.js和test.js文件是示例模块和测试用例。
示例模块
这个基本模块生成常见的 Ajax 请求。使用它来了解测试 Ajax 代码的机制。
该代码调用文件myapi.js ,您可以在此处下载。
var myapi = {
get: function(callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://jsonplaceholder.typicode.com/posts/1', true);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
callback(null, JSON.parse(xhr.responseText));
}
else {
callback(xhr.status);
}
}
};
xhr.send();
},
post: function(data, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://jsonplaceholder.typicode.com/posts', true);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
callback();
}
};
xhr.send(JSON.stringify(data));
}
};
这里有两个函数:第一个函数获取数据,另一个函数发布数据。使用JSONPlaceholder API进行快速、轻松的测试。
测试用例框架
要在继续以下场景时添加测试,请创建一个骨架文件。本指南中的文件名为test.js。
chai.should();
describe('My API', function() {
//All the tests would go here
});
为了生成测试用例,Mocha 使用describe。下一步是将测试添加到上述文件中。
请记住,chai.should()允许您包含should 样式的断言。换句话说,您可以使用类似于someValue.should.equal(12345)的语法来验证测试结果。
测试 GET 请求
在以下场景中,您将创建一个测试来验证所获取数据的 JSON 解析是否正确。由于您无法从单元测试发送 HTTP 请求,因此您可以对 XMLHttpRequest 执行以下操作。
首先将 Sinon 库包含在测试运行器中。Sinon 可让您创建测试替身,即可以替换其他替身并同时修改其行为的对象和函数。接下来,您将用您控制的替身替换 XMLHttpRequest。
按如下方式更新测试用例骨架,或者在此处下载修改后的版本。
chai.should();
describe('MyAPI', function() {
beforeEach(function() {
this.xhr = sinon.useFakeXMLHttpRequest();
this.requests = [];
this.xhr.onCreate = function(xhr) {
this.requests.push(xhr);
}.bind(this);
});
afterEach(function() {
this.xhr.restore();
});
//Tests etc. go here
});
顾名思义,您可以使用beforeEach和afterEach在每个测试之前和之后运行指定的代码片段。
在测试之前,创建一个假的 XMLHttpRequest 并将这些请求排列在一个数组中。这样,保存在this.xhr和this.requests中的值就可以在测试用例的任何地方使用了。
测试完成后,您需要恢复 XMLHttpRequest 对象的原始状态。您可以使用this.xhr.restore()轻松完成此操作。
之后,只需编写测试:
it('should parse the fetched response data as JSON', function(done) {
var data = { foo: 'bar' };
var dataJson = JSON.stringify(data);
myapi.get(function(err, result) {
result.should.deep.equal(data);
done();
});
this.requests[0].respond(200, { 'Content-Type': 'text/json' }, dataJson);
});
如您所见,为了避免在测试中重复这些值,您需要定义数据——确切地说是一个对象及其 JSON 版本。下一步是调用myapi.get,它会使用测试数据验证您的结果。随后,使用done()以便 Mocha 知道异步测试已结束。请注意done是如何用作测试函数的参数的。
最后一步,使用this.requests[0].respond。请记住,使用beforeEach会生成一个侦听器,该侦听器会将所有 XMLHttpRequests 放在this.requests中,而创建请求则使用myapi.get。
XMLHttpRequests通常不包含response函数。在伪造的XMLHttpRequests中使用response函数来对收到的请求发送响应。将状态码设置为200表示操作成功,将Content-Type标头设置为text / json表示数据格式为JSON。最后,将最后一个参数,即响应主体设置为您之前定义的dataJson变量。
现在,你的伪造 XMLHttpRequest 将假装 Web 服务器发送了你提供的 JSON。当myapi.get检查它时,它会调用回调函数,在其中比较结果和数据变量:
myapi.get(function(err, result) {
result.should.deep.equal(data);
done();
});
处理响应包括将接收到的数据配对到一个对象中。假设您已经准备好了上面的数据和dataJson变量,那么您只需将结果与它们进行比较即可。
要在您选择的浏览器中运行这些测试,只需打开testrunner.html文件,您将在其中找到有关测试通过的消息。
测试 POST 请求
要测试 POST 请求,您需要将发布的数据编码为 JSON 并在请求正文中发送:
it('should post the given response data as JSON body', function() {
var data = { hello: 'world' };
var dataJson = JSON.stringify(data);
myapi.post(data, function() { });
this.requests[0].requestBody.should.equal(dataJson);
});
与上一种情况类似,您需要在测试之前设置数据并调用myapi.post。由于您只需确保数据已成功解析为 JSON,因此您可以将回调留空。现在您需要使用断言来验证请求的行为。与之前的测试类似,您必须访问您创建的 XMLHttpRequest 并确保其requestBody<font style="vertica
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~