How to test against a DOM object in qUnit?
Asked Answered
N

2

11

I'm testing some JavaScript with qUnit. In one object I pass a DOM element, and some methods will change some properties of the element.

How can I mock a DOM object in qUnit?

I'd like to use a solution browser independent, as I test also XUL applications.

Nuri answered 1/10, 2011 at 14:55 Comment(0)
T
7

You can always create an element in JavaScript. If you don't append it (e.g. to the body), it won't be visible, so you could call it a mock element:

document.createElement('div'); // 'div' will create a '<div>'

So you can use this in a qUnit test function just as well: http://jsfiddle.net/LeMFH/.

test("test", function() {
    expect(1);

    var elem = document.createElement("div");

    elem.style.position = "absolute";

    equals(elem.style.position, "absolute");
});
Tahmosh answered 1/10, 2011 at 15:10 Comment(1)
Ok, so every time I have to set the "default" value for all the properties i have to test. I was thinking about a library with "ready" dom elements, but now i'm pretty sure your is the best solution.Nuri
M
3

I had this situation where I wanted to create a unit test for a JQuery plugin I wrote that provides simple basic tree expansion capability. I found a way to create dummy line item (“LI” element) using the QUnit “ok” method and inject the test DOM as a child of this list item, in this way the resulting manipulated DOM can be examined by expanding the test. Also if the test failed, the manipulated DOM elements will automatically be displayed by the QUnit system. The resulting QUnit output looks like the following:

QUnit test output

My solution to this problem was to create a function called “testSpace” where the line item text and test HTML can be defined so the QUnit test commands can check the resulting DOM. The following is the test code that uses this feature:

test("$.fn.tocControl", function () {
    var sTest =
          "<div>"
            + "<ul>"
                + "<li>item1</li>"
                + "<li>item2"
                    + "<ul>"
                        + "<li>s1item1</li>"
                        + "<li>s1item2"
                        + "<ul>"
                            + "<li>s2item1</li>"
                            + "<li>s2item2"
                            + "</li>"
                            + "<li>s2item3</li>"
                            + "<li>s2item4</li>"
                        + "</ul>"
                        + "</li>"
                        + "<li>s1item3</li>"
                        + "<li>s1item4</li>"
                    + "</ul>"
                + "</li>"
                + "<li>item3</li>"
                + "<li>item4</li>"
                + "<li>item5</li>"
            + "</ul>"
        + "</div>";

    // Create the test HTML here.
    var jqTest = testSpace("$.fn.tocControl.test", sTest);

    // Invoke the JQuery method to test.
    jqTest.find("ul").tocControl();

    // QUnit tests check if DOM resulting object is as expected.
    equal(jqTest.find("ul.ea-toc-control").length, 1, '$("div#testSpace ul.tocControl").length');
    equal(jqTest.find("ul:first").hasClass("ea-toc-control"), true, '$("div#testSpace ul:first").hasClass("tocControl")');
});

The “testSpace” function defines the line item using the QUnit “ok” method, but initially constructs the DOM objects in a temporary location until the QUnit system defines the line item. This function is defined as follows:

function testSpace(sName, sHTML) {
    ok(true, sName);

    var jqTestItem = $("ol#qunit-tests > li:last");
    jqTestItem.append('<div id="testSpaceContainer" style="display:none;">' + sHTML + '</div>');

    var jqTestSpace = jqTestItem.children("div#testSpaceContainer:first");

    var moveTestSpaceStart = $.TimeStamp();
    var moveTestSpace = function () {
        var jqTestArea = jqTestItem.find("ol > li:contains(" + sName + ")").filter(function () { return $(this).text() == sName; });
        if (jqTestArea.length <= 0) {
            if (!$.HasTimedOut(moveTestSpaceStart, 5000)) setTimeout(moveTestSpace, 200);
            return false;
        }
        var oTestSpace = jqTestSpace.detach();
        jqTestArea.append(oTestSpace);
        jqTestArea.find("div#testSpaceContainer").show();
        return true;
    }
    moveTestSpace();

    return jqTestSpace.children().first();
}
Maudmaude answered 1/4, 2012 at 18:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.