【问题标题】:QUnit how to test events?QUnit如何测试事件?
【发布时间】:2014-06-19 00:18:36
【问题描述】:

我有一个带有如下按钮的 html 页面:

<input id='btnSubmit' type='button'/>

触发在 document.ready 函数中定义的点击处理程序,如下所示:

$(document).ready(function () { 

$("#btnSubmit").click(function () {
            $.ajax({
                url: myUrl,
                data: { 'startDate': startDateId, 'endDate': endDateId },
                dataType: "json",
                type: "POST",
                cache: false,
                success: function (data) {
                    alert('yay!');
                },
                error: function (request, status, error) {
                    LogError(request, startDate, error);
                    location.href = "error/error";
                }
            });
      }
}

现在我想用 QUnit 测试这个功能,所以我在一个单独的 html 文件中构建了以下单元测试,该文件引用了包含上述代码块的 .js 文件:

QUnit.test("Test", function (assert) {
            var fixture = $("#qunit-fixture");
            fixture.append("<input type='button' id='btnSubmit'/>");
            $("#btnSubmit").trigger("click");
            assert(something);        
});

我在这个文件中有许多其他测试都可以正常执行,但是每当我尝试创建一个测试来执行 qunit-fixture 中元素的事件处理程序时,它都无法调用实际的处理程序。

我知道我需要模拟 ajax 调用才能真正测试此功能。但我首先需要确定如何触发事件。如何使用 qunit 正确触发和测试事件?

【问题讨论】:

  • 事件处理程序在页面加载时添加到按钮中,并且您正在测试中添加一个按钮。我认为事件处理程序未添加到您的测试中添加的按钮中。您可以在单元测试中将事件处理程序添加到按钮或使用其他工具来测试事件处理(如Selenium)。

标签: jquery unit-testing qunit


【解决方案1】:

好的,我最终只是在测试 html 文档的正文中添加了按钮,而不是通过 qunit-fixture 元素。现在 $("#btnSubmit").trigger("click");在被测 JS 文件中触发实际的事件处理程序。哦,我做的另一件事是将按钮标记为隐藏,这不是必需的,但会清理测试文档。所以最终版本是这样的:

要测试的html文档:

<html>
<head>
<body>
    <input id='btnSubmit' type='button'/>
<...

要测试的 JavaScript:

$(document).ready(function () { 

$("#btnSubmit").click(function () {
            $.ajax({
                url: myUrl,
                data: { 'startDate': startDateId, 'endDate': endDateId },
                dataType: "json",
                type: "POST",
                cache: false,
                success: function (data) {
                    alert('yeah!');
                },
                error: function (request, status, error) {
                    LogError(request, startDate, error);
                    location.href = "error/error";
                }
            });
      }
}

QUnit 测试文件:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>QUnit Tests</title>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.14.0.css">
    <script src="http://code.jquery.com/qunit/qunit-1.14.0.js"></script>
</head>
<body>
    <div id="qunit"></div>
    <div id="qunit-fixture"></div>
    <input id='btnSubmit' type='button' hidden='hidden'/>
    <script>
QUnit.test("Test", function (assert) {
            $("#btnSubmit").trigger("click");
            //assertions...       
});

【讨论】:

  • 我有一个类似的问题,我发现可以通过使用事件委托$('#element').on('click', 'a', ...); 解决这个问题,这让我想到这是因为当#qunit-fixture 为每个测试重置时,它正在删除元素并替换它们,从而丢失附加到元素的事件。这与使用 jQuery 将元素添加到页面上时相同,除非您使用事件委托或将它们附加到新元素,否则不会附加事件。希望这是有道理的,并解释了为什么将按钮移到 #qunit-fixture 之外有效
【解决方案2】:

这里是 QUnit 中存在的事件列表和简单实现

EVENT 还有DESCRIPTION

  1. begin : 测试套件开始时触发
  2. done : 测试套件结束时触发
  3. log:断言完成时触发
  4. moduleDone : 模块完成时触发
  5. moduleStart : 模块启动时触发
  6. testDone : 测试完成时触发
  7. testStart : 测试开始时触发

    QUnit.begin(function( details ) {
       console.log( "Event for Test Suit Starting." );
    });
    
    QUnit.done(function( details ) {
      console.log( "Event for Test Suit Ending. Results: Total: ", details.total, " Failed: ", details.failed, " Passed: ", details.passed, " Runtime: ", details.runtime );
    });
    
    QUnit.log(function( details ) {
     console.log( "Event for Assertion complete. Details: ", details.result, details.message );
    });
    
    QUnit.moduleStart(function( details ) {
      console.log( "Event for Starting module: ", details.module );
    });
    
    QUnit.moduleDone(function( details ) {
     console.log( "Event for Finished Running Module: ", details.name, "Failed/total: ", details.failed, details.total );
     });
    
    QUnit.testStart(function( details ) {
     console.log( "Event for Now Running Test: ", details.module, details.name );
    });
    
    QUnit.testDone(function( details ) {
     console.log( "Event for Finished Running Test: ", details.module, details.name, "Failed/total: ", details.failed, details.total, details.duration );
    });
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多