gpt4 book ai didi

jquery - 如何使用 Sinon 和 QUnit 对 $(function () { ... }) block 进行单元测试?

转载 作者:行者123 更新时间:2023-12-01 01:26:05 26 4
gpt4 key购买 nike

我在 JS 文件中有这样的代码(当然是简化的):

$(function () {
var num;
$.getJSON('./getNumber.php', function (n) {
num = n;
});

$('#id').on('click', function () { alert(num); });
});

我需要编写两个单元测试:

  1. 确保脚本发送 ./getNumber.php页面加载时向服务器请求
  2. 确保何时 #id单击后,num收到警报。

显然我需要 FakeXmlHTTPRequest 并模拟 alert函数,甚至可能监视 $.getJSON 。但是我不确定在保持两个原子性的同时编写测试的正确方法是什么。

我认为这样做的唯一方法就是动态注入(inject) <script>每个测试的 block ;但我就是觉得这样不对。正确的方法是什么?谢谢。

编辑:根据SO之外的评论,我需要学习的是编写可测试的Javascript,而不是尝试为可测试性较低的东西提出测试用例。如果有人能给我一些关于重写这段代码的建议,我也将不胜感激。

最佳答案

您的问题没有一个正确答案,但有很多值得学习的好原则。考虑以下代码。我重构了你的例子。我将在下面解释我所做的一切。

// Define your module in a self-executing function.
// This module is now completely unit testable.
var myModule = (function () {
var num;

function getNum() {
$.getJSON('./getNumber.php', function (n) {
num = n;
});
}

function alertNum() {
alert(num);
}

// this returned object will by set to myModule and will publicly
// expose the necessary functions
return {
getNum: getNum,
alertNum: alertNum
};
})();

// wire up your events
$(function() {
$("#id").on('click', myModule.alertNum);
});

对于这个简单的代码来说,这个示例显然有些过大,但它应该会给您一些好主意。

  1. 您的核心功能现已封装在模块中。您可以在模块内保留其他私有(private)函数和变量(例如 num),但现在可以测试通过返回对象公开公开的所有内容。 (见下面的注释)

  2. 我已连接模块外部的事件。如果您的模块很大,您甚至可能想将此代码放在另一个脚本中。无论哪种方式,它都会以一种更像 MVC 的方法来分离您的关注点。您可以测试这段代码,但实际上不必这样做;它应该是非常简单的 jQuery,围绕它进行测试只不过是测试 jQuery 库,该库已经经过 jQuery 团队的彻底测试。

  3. 这可能看起来很奇怪,但不要在模块中使用任何 jQuery 选择器!如果您的模块需要一个元素,请将其作为函数参数传递。有一些方法可以消除这些东西,但这确实很麻烦,如果您正确地分离了您的关注点,则没有必要。我的大多数模块(或其中的对象)最终都会有一个 init() 方法,我可以在其中传递内容。 -- 您可能仍然选择对模块内的元素使用 jQuery 的 .find() 方法。这更多的是只有您可以根据模块的特定需求做出的判断。这样做将需要您在测试中对 DOM 元素进行更详细的模拟,但有时它比将数十个元素传递到 init() 中更容易(只需传递主容器即可)。

<小时/>

注意:我强烈建议使用 RequireJS或另一个用于管理模块的 AMD 模块加载器。这将使上面的 myModule 之类的东西远离全局命名空间。不过,使用 QUnit 设置 Require 有点挑剔,一旦您掌握了单元测试,这可能是一个需要解决的问题。

关于jquery - 如何使用 Sinon 和 QUnit 对 $(function () { ... }) block 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13547840/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com