QUnit how to test events?

2019-09-18 05:20发布

问题:

I have an html page with a button like this:

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

which triggers a click handler defined within the document.ready function like this:

$(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";
                }
            });
      }
}

Now I want to test this functionality with QUnit, so I have built the following unit test in a separate html file that references the .js file containing the code blocks above:

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

I have numerous other tests within this file that are all executing properly, but whenever I try to create a test that exercises the event handler of an element within the qunit-fixture, it fails to call the actual handler.

I understand that I will need to mock the ajax call to truly test this function. But I first need to determine how to trigger the event. How do I properly trigger and test events with qunit?

回答1:

OK, I ended up just adding the button within the body of the test html document rather than through the qunit-fixture element. Now $("#btnSubmit").trigger("click"); triggers the actual event handler within the JS file under test. Oh, one other thing I did was mark the button as hidden which isn't necessary, but cleans up the test document. So the final version looks like this:

html document to test:

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

JavaScript to test:

$(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 test file:

<!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...       
});


回答2:

here is list of events present in QUnit and simple implementation

EVENT and there DESCRIPTION

  1. begin : Fire when the test suite begins
  2. done : Fire when the test suite ends
  3. log : Fire when an assertion completes
  4. moduleDone : Fire when a module completes
  5. moduleStart : Fire when a module start
  6. testDone : Fire when a test completes
  7. testStart : Fire when a test starts

    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 );
    });