如何对jQuery选择器进行单元测试?

时间:2009-10-30 01:04:12

标签: javascript jquery unit-testing qunit

只是一个简单的问题......我目前有以下带有选择器的jQuery代码。

var ID = "idControl"
function doesTreeViewExist()
{
    if($('#' + ID).length == 0)
    {
        return false;
    }
    else
    {
        return true;
    }
}

我想知道如何使用QUnit编写测试来测试选择器?更具体地说,我在编写语法/代码时遇到了麻烦。

编辑:

好的,假设现在我想模拟选择器调用,因为我无法访问实际的网站。我正在使用JsTestDriver作为我的测试工具,这意味着我无法触摸运行测试的浏览器(否则测试运行将停止)。在这种情况下怎么样?我怎么可能测试代码?

感谢。

2 个答案:

答案 0 :(得分:9)

您发布的功能可以大大简化:

var ID = "idControl";
function doesTreeViewExist() {
  return !!$('#' + ID).length;
}

使用!!构造(双按位NOT ),将length属性转换为布尔值,仅当长度为零时才返回false

谈到qUnit,你可以轻松地设置一个简单的测试:

test("Your selector test", function() {
  ok($('#idControl').length > 0, "idControl exists");
  // or simply
  ok($('#idControl').length, "idControl exists");
});

ok函数执行布尔断言,相当于JUnit的assertTrue。

答案 1 :(得分:4)

我手动测试选择器,然后将它们传递给使用它们的代码。然后我可以对使用它们的代码进行单元测试。如果您只想测试选择器,则需要访问它所影响的HTML。您的测试可能包含目标HTML,例如:

test("selector works", function() {
    var html = $('<input type="select"><option value=0/></input');

    var result = $('option', html);

    ok(result.count() == 1);
});

但是我不这样做......我把选择器放在代码的边缘,这样我就可以快速找到它们并在调试器下逐步完成它们。我将有一个简单的类,其属性是那些选择器。然后我将模拟/存根这个简单的类,所以我可以编写依赖于那些选择器的所有代码。   我不测试我的选择器的原因是因为它们所针对的HTML是由ASP.NET代码生成的,并且很难从javascript测试中获得。但我可以将它们包装在一个Humble Object(“http://xunitpatterns.com/Humble Object.html”)中,然后测试依赖于那个不起眼的对象的代码。这是一个简单的包装类,我可以用测试双精度替换:

var createSelectWidget = function(rootSelector)
{
    return {
        userText : $('span', rootSelector),
        inputList : $('option', rootSelector),
    };
}

无论您使用哪种依赖注入模式,您都可以将其存储如下。假设我的小部件有一个选择输入来读取值,并且我希望将一些结果写入:

var createSelectWidgetStub = function()
{
    return {
        userText : { text = function() {}},
        inputList : { val = function() {}},
    };
}

然后,我可以在测试中传递此存根,我希望隔离依赖项,但不关心与该依赖项的交互。当我想验证与依赖项的交互时,我可以使用JSMock来模拟它。假设我想验证与输入列表的交互,我会准备一个带有一个元素mock的存根:

var selectMock = createSelectWidgetStub();
selectMock.inputList = mc.createMock(selectMock.inputList);