0Pricing
jQuery Academy · 课时

编写有效的 jQuery 测试

练习为 DOM 操作、事件处理器和 AJAX 调用编写单元测试,确保 jQuery 组件可靠且无错误。

编写有效的 jQuery 测试 是 CoddyKit 上的免费 jQuery Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 jQuery Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 jQuery Academy 课程共包含 3 节课。

掌握 jQuery 测试编写

欢迎学习!本课将深入介绍如何为 jQuery 应用程序编写有效的单元测试。我们将重点学习验证 DOM 操作、事件处理和异步 AJAX 调用的实用策略。

稳健的测试可以确保代码按预期运行,并有助于防止项目发展过程中的回归问题。

验证 DOM 更改

当 jQuery 代码修改文档对象模型(DOM)时,测试应验证这些更改。其中包括检查元素的创建、移除、属性更改或文本更新。

通常,您会在操作完成后选择该元素,并断言其属性。

<!DOCTYPE html>
<html>
<head>
  <title>Test DOM Change</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
  <div id="app"></div>

  <script>
    $(document).ready(function() {
      // Simulate a jQuery operation
      $('#app').append('<p class="message">Hello world!</p>');

      // Simulate a test assertion
      if ($('#app .message').length === 1 && $('#app .message').text() === 'Hello world!') {
        console.log("PASS: Element appended and text is correct.");
      } else {
        console.log("FAIL: Element not found or text is incorrect.");
      }
    });
  </script>
</body>
</html>

隔离 DOM 测试

为了保证 DOM 测试可靠,必须确保每个测试都在干净且相互隔离的环境中运行。大多数测试框架都提供 beforeEach 和 afterEach 钩子。

  • beforeEach:为新测试设置初始 DOM 状态。
  • afterEach:清理测试所做的所有 DOM 更改。

这样可以防止测试之间相互干扰。

测试类的更改

让我们测试一种常见的 DOM 操作:添加或移除 CSS 类。您可以在 jQuery 函数运行后,断言元素是否 .hasClass() 某个特定的类。

<!DOCTYPE html>
<html>
<head>
  <title>Test Class Toggle</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
  <button id="toggleBtn" class="active">Toggle</button>

  <script>
    $(document).ready(function() {
      // Function to test
      function toggleActiveClass(element) {
        $(element).toggleClass('active');
      }

      // Test Case 1: Active class is present initially
      if ($('#toggleBtn').hasClass('active')) {
        console.log("PASS: Initial state has 'active' class.");
      } else {
        console.log("FAIL: Initial state missing 'active' class.");
      }

      // Run the function
      toggleActiveClass('#toggleBtn');

      // Test Case 2: Active class should be removed
      if (!$('#toggleBtn').hasClass('active')) {
        console.log("PASS: 'active' class removed after toggle.");
      } else {
        console.log("FAIL: 'active' class not removed.");
      }
    });
  </script>
</body>
</html>

模拟用户事件

要测试事件处理器,需要模拟用户交互。jQuery 的 .trigger() 方法非常适合完成此操作。它可以在选定元素上触发任何事件(例如 'click'、'submit'、'change')。

触发事件后,您可以断言预期结果,例如 DOM 更改或函数调用。

验证点击事件

下面介绍如何测试点击事件是否正确更新用户界面的一部分。我们将触发一次点击,然后检查元素的新文本内容。

<!DOCTYPE html>
<html>
<head>
  <title>Test Click Event</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
  <button id="myButton">Click Me</button>
  <p id="status">Not clicked yet.</p>

  <script>
    $(document).ready(function() {
      // Attach the event handler
      $('#myButton').on('click', function() {
        $('#status').text('Button was clicked!');
      });

      // Simulate the click event
      $('#myButton').trigger('click');

      // Simulate assertion
      if ($('#status').text() === 'Button was clicked!') {
        console.log("PASS: Status updated after click.");
      } else {
        console.log("FAIL: Status not updated correctly.");
      }
    });
  </script>
</body>
</html>

事件状态断言

事件处理器往往不只是更改 DOM;它们还可能更新数据属性或应用程序内部状态。测试也应验证这些不太明显的更改。

您可以在事件触发后检查 .data() 的值或其他属性。

<!DOCTYPE html>
<html>
<head>
  <title>Test Event Data</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
  <button id="counterBtn" data-count="0">Increase Count</button>

  <script>
    $(document).ready(function() {
      // Attach event handler
      $('#counterBtn').on('click', function() {
        let currentCount = parseInt($(this).data('count'));
        $(this).data('count', currentCount + 1);
      });

      // Initial check
      if ($('#counterBtn').data('count') === 0) {
        console.log("PASS: Initial count is 0.");
      } else {
        console.log("FAIL: Initial count is not 0.");
      }

      // Trigger click
      $('#counterBtn').trigger('click');

      // Assert after first click
      if ($('#counterBtn').data('count') === 1) {
        console.log("PASS: Count is 1 after first click.");
      } else {
        console.log("FAIL: Count is not 1.");
      }

      // Trigger another click
      $('#counterBtn').trigger('click');

      // Assert after second click
      if ($('#counterBtn').data('count') === 2) {
        console.log("PASS: Count is 2 after second click.");
      } else {
        console.log("FAIL: Count is not 2.");
      }
    });
  </script>
</body>
</html>

测试异步 AJAX

测试真实的 AJAX 调用可能速度较慢、不可靠,并且依赖外部服务。解决方案是模拟 AJAX 请求。

模拟是指用受控且预先定义的响应替代实际网络调用。这样可以让测试快速且一致地运行,只关注客户端逻辑。

实现 AJAX 模拟

您可以使用 Sinon.js 等工具,或者在简单情况下重写 jQuery 的 AJAX 行为。一种用于测试的基本成功响应模拟方式,是暂时修改 $.ajax,或使用模拟库。

这里,我们将在不发起真实网络请求的情况下模拟成功回调。

<!DOCTYPE html>
<html>
<head>
  <title>Mock AJAX Test</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
  <div id="data-display">Loading...</div>

  <script>
    $(document).ready(function() {
      // Store original $.ajax for restoration
      const originalAjax = $.ajax;

      // Mock $.ajax for this test
      $.ajax = function(options) {
        // Simulate a successful response
        const deferred = $.Deferred();
        deferred.resolve({ message: "Mocked data received!" });
        return deferred.promise();
      };

      // Your function that makes an AJAX call
      function fetchDataAndDisplay() {
        $.ajax({
          url: '/api/data',
          method: 'GET'
        }).done(function(response) {
          $('#data-display').text(response.message);
        }).fail(function() {
          $('#data-display').text('Error fetching data.');
        });
      }

      // Run the function under test
      fetchDataAndDisplay();

      // Simulate assertion after a short delay (for async effect)
      setTimeout(function() {
        if ($('#data-display').text() === 'Mocked data received!') {
          console.log("PASS: AJAX call successfully mocked and handled.");
        } else {
          console.log("FAIL: AJAX mock failed or handler incorrect.");
        }
        // Restore original $.ajax (important for real apps)
        $.ajax = originalAjax;
      }, 10); // Small delay to allow promise resolution
    });
  </script>
</body>
</html>

快速检查

您已经了解了如何测试 DOM 操作、事件和 AJAX。在测试中,以编程方式触发元素事件通常使用哪个 jQuery 方法?

回顾:有效的 jQuery 测试

恭喜您!您已经学习了如何为 jQuery 应用程序的各个方面编写有效的单元测试。

  • 我们学习了如何断言对 DOM 的更改,以及验证元素的属性和内容。
  • 我们学习了如何模拟用户交互,并使用 .trigger() 测试事件处理器。
  • 最后,我们讨论了如何模拟 AJAX 请求,以确保异步操作的测试快速且可靠。

这些技术对于构建稳健且易于维护的 jQuery 代码至关重要。

常见问题解答

「编写有效的 jQuery 测试」课时是免费的吗?

是的 — 「编写有效的 jQuery 测试」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 jQuery Academy 课程的其余内容,请升级到 CoddyKit PRO。 jQuery Academy 课程共包含 3 节课。

「编写有效的 jQuery 测试」这节课中我会学到什么?

练习为 DOM 操作、事件处理器和 AJAX 调用编写单元测试,确保 jQuery 组件可靠且无错误。 你通过在浏览器中直接运行的动手代码来练习 jQuery Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 jQuery Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 jQuery Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。

「编写有效的 jQuery 测试」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 jQuery Academy 课中编写并运行代码吗?

能。每节 jQuery Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. jQuery 单元测试简介
  2. 设置测试环境
  3. 编写有效的 jQuery 测试
← 返回 jQuery Academy