单元测试javascript函数'在不知情的情况下被用于其他地方

Unit testing javascript function that's unknowingly used elsewhere

本文关键字:情况下 用于 其他 不知情 函数 javascript 单元测试      更新时间:2023-09-26

我刚开始单元测试,请耐心等待。

举以下"愚蠢"的例子。我在页面上创建了一个要将函数绑定到的元素对象。我为test.myFunction设置了一个单元测试,并确保它返回"textToReturn"。

var global = {
  o_bindings : [
    {
      object: '#element1',
      event: 'keyup',
      selector: '', 
      data: '',
      theFunction: function() {
        test.myFunction(textToReturn);
      }
    },
    // .... lots of other code ....
    {
      object: '#element2',
      event: 'keyup',
      selector: '', 
      data: '',
      theFunction: function() {
        test.myFunction(textToReturn);
      }
    }
  ]
};

$(document).ready(function() { 
  for (var i=0; i < global.o_bindings.length; i++) {
    var o = global.o_bindings[i];
    $(o.object).on(o.event, o.selector, o.data, o.theFunction);
  }
});

一年后,我再次访问,并决定#element2每次都应该返回相同的文本,所以我在函数中对其进行硬编码,并更新原始对象的那部分:

    {
      object: '#element2',
      event: 'keyup',
      selector: '', 
      data: '',
      theFunction: function() {
        test.myFunction()
      }
    }

我忘记了这个函数也用于#element1,并相应地更新了我的单元测试,所以它总是返回相同的文本。

单元测试会通过,但#element1不会按预期工作。

我是不是错过了什么?或者这会在功能测试中被发现,因为它超出了单元测试的范围?如有任何建议,我们将不胜感激。

我不确定我是否完全理解您的代码,但一般来说,"单元测试"应该测试尽可能低级别的函数。在这种情况下,我认为这是test.myFunction()。所以,如果在过去它接受了一个论点,然后基于这个论点返回了一些东西,而现在它没有,那么你是否传递任何东西都无关紧要。换句话说,如果JavaScript函数根本不使用参数,那么传入(或不传入)它们就无关紧要了(因此不会影响测试的成功)

在您的情况(如上)中,在代码更改为不再使用输入之后使用test.myFunction(textToReturn)并不重要,因为无论哪种方式,该方法都可以正常工作。也就是说,假设您在theFunction()中有一些代码,期望正确的textToReturn值,那么您将为theFunction()编写一个测试来检查这一点。这里有一个更简单的例子:

// sort of like your `test.myFunction()`
function foo() {
    return "static value";
}
// the place where you remembered to change it...
function bar() {
    $("#" + id).text( foo() );
}
// the place where you forgot to change it
function baz(id) {
    $("#" + id).text( foo("some other value") );
}

对于上面的源代码,我将对每个函数进行测试,包括通过测试和预期失败的测试。以下是一些测试(还有更多):

QUnit.test("make sure foo works", function(assert) {
    var v = foo();
    assert.equal(v, "static value", "The value returned by foo should be correct");
});
// I would have added this one after the change to your `test.myFunction()`
QUnit.test("make sure foo works with input", function(assert) {
    var v = foo("some other value");
    assert.equal(v, "static value", "The value returned by foo does not change with input");
});
QUnit.test("make sure bar works", function(assert) {
    bar("theElementId");
    var t = $("#theElementId").text();
    assert.equal(t, "static value", "The value in the element should be correct");
});
/*
// this is the ORIGINAL test for baz()
// It would have failed after the code change
QUnit.test("make sure baz works", function(assert) {
    baz("theElementId");
    var t = $("#theElementId").text();
    assert.equal(t, "some other value", "The value in the element should be correct based on input to foo()");
});
*/
// but I would CHANGE the test above to this:
QUnit.test("make sure baz works", function(assert) {
    baz("theElementId");
    var t = $("#theElementId").text();
    assert.equal(t, "static value", "The value in the element should be correct");
});

请注意,第四次测试可能会失败,从而突出了我忘记更新baz()的事实。