测试事件处理程序

时间:2016-10-10 08:25:36

标签: javascript

我有一个事件处理程序,它根据点击操作修改一些全局变量。我该怎么测试呢?例如:

function initEvent() {
  function enable() {
    var arr = Context.get('arr');
    arr.push('aaa');
  };
  function disable() {
    var arr = Context.get('arr');
    arr.push('bbb');
  };
  $('#content').on('click', '#element', function () {
    if (this.checked) {
      enable();
    } else {
      disable();
    }
  });
};

这是我在呈现HTML后调用的函数。它根据用户操作调用enable()disable()函数。我想测试这些函数并检查它们是否正常运行。我怎么能这样做?

3 个答案:

答案 0 :(得分:0)

您可以执行的一项简单测试enabledisable和点击处理程序是创建一个功能,用于检查arrContext的内容,并调用它在点击处理程序中的每个函数之后添加一些内容到arr

在代码中测试条件的一般方法是使用断言,如果传入它们的条件为false,则会抛出错误。您可以仅使用console.assert

$('#content').on('click', '#element', function() {
  if (this.checked) {
    enable();
    // assert last element in `arr` is the enabled string 'aaa'
    console.assert(
      Context.get('arr')[Context.get('arr').length - 1] === 'aaa',
      'enable() works'
    );
  } else {
    disable();
    // assert last element in `arr` is the disabled string 'bbb'
    console.assert(
      Context.get('arr')[Context.get('arr').length - 1] === 'bbb',
      'disable() works'
    );
  }
});

如果在单击元素后运行了任何测试,您知道initEvent分配了点击处理程序并且它可以正常工作。然后,您只需将checked标记切换为测试enable() / disable()

如果浏览器控制台中没有错误,则测试已通过。否则,控制台中将出现错误,其中包含作为console.assert的第二个参数传递的消息。

您甚至可以创建辅助函数来简化测试:

function assertLastElementInContextArr(elem, msg) {
  var arr = Context.get('arr');
  // assert last item in `arr` is equal to `elem`
  console.assert(arr[arr.length - 1] === elem, msg);
}

$('#content').on('click', '#element', function() {
  if (this.checked) {
    enable();
    // assert last element in `arr` is the enabled string 'aaa'
    assertLastElementInContextArr('aaa', 'enable() works');
  } else {
    disable();
    // assert last element in `arr` is the disabled string 'bbb'
    assertLastElementInContextArr('bbb', 'disable() works');
  }
});
根据您的评论

编辑

  

但是如何模拟点击事件?我的意思是,我想自动测试所有这些事件,不,我不得不以某种方式自动触发点击。我该怎么做?

如果要以编程方式调用click事件,可以使用JS在代码中触发它们。由于你使用的是jQuery,它已经附带了一个方法trigger来实现这一点。

您需要做的就是:

$('#content').trigger('click')

它将激活你的点击处理程序并从上面运行断言测试。

事实上,jQuery甚至为特定事件提供了别名处理程序,因此您可以这样做:

$('#content').click();

要自动化测试,您可以创建一个触发点击的功能,并设置checked状态,以测试两种情况。

function test(checked) {
  var elem = $('#content');
  elem.prop('checked', checked);
  elem.click();
}

要注意的重要一点是,这些事件将异步发生,因此如果您要触发多次点击,您必须采取措施管理正确的测试订单。否则,您会将checked设置为true,触发click,然后再运行第二个测试,将checked设置为false >点击事件甚至发生。

出于演示目的,这里有一种方法可以安全地测试多个连续点击,方法是添加一个事件处理程序,仅用于测试并在完成后删除它。这项工作的一个要求是在附加了所有其他处理程序之后附加处理程序,以确保测试处理程序最后运行。此外,您还可以在此处运行断言,以免污染代码并使测试完全分离:

function test(checked, value, msg, done) {
  var elem = $('#content');
  elem.prop('checked', checked);

  // attach a test event handler and trigger the click
  elem.on('click', testClick);
  elem.click();

  // once the click is executed, 
  // remove the test handler,
  // run the assertions and then
  // call the callback to signal the test is done
  function testClick() {
    elem.off('click', runTest);
    assertLastElementInContextArr(value, msg);
    done();
  }
}

// run your code before the tests
initEvent();

// test enable(), then once that's done, test disable()
test(true, 'aaa', 'enable() works', function() {
  test(false, 'bbb', 'disable() works', function() {
    console.log('All tests finished');
  });
});

如果你要像这样测试你的整个应用,你可能想要使用像QUnitMochaJasmine这样的测试框架来处理所有这些异步问题,为您提供了一个很好的API。

答案 1 :(得分:0)

您想测试您的代码。您永远不应使用console.logalert来测试代码。这些非常适合动态调试,但它们不是测试工具。这些促进了手动测试,您需要手动运行代码并查看该传递,这是浪费时间。

在这种情况下你应该使用Jasmine(你可以使用其他测试框架,尽管Jasmine非常简单)来测试你的代码。你可以设置浏览器测试或无头测试,这超出了这个问题的范围,有很多关于这个主题的教程。

现在,为了测试这段代码,我假设Context有一个静态方法get,它返回一个位于Context IIFE范围内的数组。如果情况不同,请随意调整规格并使其满足您的需求,或者如果您遇到困难,请更新此问题或在Stackoverflow上询问另一个问题。

我已经设置了Jasmine,用jasmine-fixture来测试你的代码,jQuery点击事件行为。在这个plunk中,您将找到所需的一切。

我正在使用浏览器测试代码,所以我需要jasmine的html记者。 真正的测试是在script-spec.js中,我使用Jasmine的API,通过描述规范套件(使用describe)并使用it方法定义每个规范。

beforeEach中,我准备在每个规范执行之前运行的代码。从本质上讲,我创建了一个带有div ID的简单#content和带有input id的复选框类型的子#element元素。我是通过使用

来做到这一点的

setFixtures('<div id="content"><input type="checkbox" id="element" /></div>');

这是jasmine-fixture库提供的方法。

现在我可以测试代码,连接规范:

  it("Should return an array with 'aaa' element when #element is checked", function() {
    // Arrange
    initEvent();
    var checkbox = $("#content").find("#element");

    // Act
    checkbox.click();

    // Assert
    expect(Context.get('arr').length).toBe(1);
    expect(Context.get('arr')).toEqual(['aaa']);
  });

我运行initEvent方法并获取checkbox元素的引用。在Act部分中,我手动单击该元素,将其标记为选中,这是正常行为。在Assert中,我测试Context.get('arr')返回值。

同样,plunk的链接是here

希望这有帮助。

答案 2 :(得分:-1)

只需在函数调用中添加console.log(<some variable>)alert(<some variable>)即可。 e.g:

function initEvent() {
  function enable() {
    alert("enable called!");
    var arr = Context.get('arr');
    arr.push('aaa');
  };
  function disable() {
    alert("disable called!");
    var arr = Context.get('arr');
    arr.push('bbb');
  };
  $('#content').on('click', '#element', function () {
    alert("click occured!");
    if (this.checked) {
      enable();
    } else {
      disable();
    }
  });
};

或者使用您的浏览器开发人员工具在这些位置设置断点。

相关问题