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.
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.
Share Improve this question edited Oct 1, 2011 at 15:10 pimvdb 155k80 gold badges311 silver badges356 bronze badges asked Oct 1, 2011 at 14:55 Manuel BittoManuel Bitto 5,2536 gold badges42 silver badges48 bronze badges2 Answers
Reset to default 7You 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/LeMFH/.
test("test", function() {
expect(1);
var elem = document.createElement("div");
elem.style.position = "absolute";
equals(elem.style.position, "absolute");
});
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:
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 mands 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();
}