【发布时间】:2014-08-08 22:25:42
【问题描述】:
我有一个使用 D3 和 Angular 编写的折线图组件。它具有用于更改 x 轴比例的可拖动条。现在我正在尝试使用 Karma/Jasmine 测试组件。我在单元测试中触发拖动事件时遇到问题。
其他事件,如鼠标悬停和单击都可以很好地触发。我认为这是 d3 中“拖动”事件的综合实现导致了问题。
这是我用来触发拖动的代码(此类代码会在测试 html 页面上触发正确的 d3 拖动事件,但在单元测试中失败)。
var leftBar = element.find(".left-bar")[0];
var evObjStart = document.createEvent("MouseEvents");
evObjStart.initMouseEvent("mousedown", true, true, window, 1, 12, 320, 12, 320, false, false, false, false, 0, null);
var evObj = document.createEvent("MouseEvents");
evObj.initMouseEvent("mousemove", true, true, window, 1, 100, 320, 100, 320, false, false, false, false, 0, null);
var evObjEnd = document.createEvent("MouseEvents");
evObjEnd.initMouseEvent("mouseup", true, true, window, 1, 200, 320, 200, 320, false, false, false, false, 0, null);
leftBar.dispatchEvent(evObjStart);
leftBar.dispatchEvent(evObj);
leftBar.dispatchEvent(evObjEnd);
我发现只有第一个事件被正确分派(leftBar.dispatchEvent(evObjStart))。
其他两个事件根本没有调度。 leftBar 变量 100% 正确。我完全不知道在哪里搜索错误。
附言我尝试生成“dragstart”、“drag”和“dragend”事件,但是浏览器中的 d3 没有正确处理它们(在控制台的基本测试示例中不起作用)。 Mousedown/mousemove/mouseup 序列在浏览器中正常工作,但在单元测试中仅调度 mousedown。将非常感谢任何帮助或想法。
【问题讨论】:
-
我认为,如果您直接使用模拟参数调用处理程序并相信浏览器供应商正确实施了事件处理,那么您的生活会大大简化。
-
谢谢,本!我的用例有点复杂。实际上,我的代码位于 angular 指令中,因此无法从外部访问处理程序。使它们可访问实际上会破坏将此指令用作单独插件的概念(这并不意味着影响外部 html 或变量)。我想编写一个“仅测试”指令版本,处理程序从外部可见,但如果我有一个用于分发的组件和另一个用于测试的组件,这与单元测试的想法有些冲突。希望我的解释有道理)
-
您可以通过执行各种操作使处理程序从外部访问。例如,将它们作为成员或静态属性添加到指令的控制器中。如果已正确注册,则可以使用 $controller 检索。
-
我想我会通过创建指令来执行 d3 鼠标事件绑定来解决这个问题,然后在更像是模板/控制器构造的指令中使用这些指令。您所做的一个指令可能会尝试做太多事情,这使得测试变得困难。
-
谢谢!现在会研究那个。你是对的,目前我将所有代码都放在一个指令中。 Angular 用于传递/更新数据,所有处理都在 d3 内部完成。我会尝试重新定义架构,谢谢你的想法!
标签: javascript angularjs unit-testing d3.js jasmine