【问题标题】:Testing angular mousedown, mousemove, mouseup测试角度 mousedown、mousemove、mouseup
【发布时间】:2016-06-16 17:25:50
【问题描述】:

在angular docs的指令部分

他们粗略地提供了如何制作拖曳物的示例。

我的问题是您将如何测试他们的示例/实现:

  var startX = 0, startY = 0;
  scope.x = 0;
  scope.y = 0;
  element.css({
    top: scope.y, 
    left: scope.x
  });

  element.on('mousedown', function(event) {
    // Prevent default dragging of selected content
    event.preventDefault();
    startX = event.pageX - scope.x;
    startY = event.pageY - scope.y;
    $document.on('mousemove', mousemove);
    $document.on('mouseup', mouseup);
  });

  function mousemove(event) {
    scope.y = event.pageY - startY;
    scope.x = event.pageX - startX;
    element.css({
      top: scope.y + 'px',
      left: scope.x + 'px'
    });
  }

  function mouseup() {
    $document.off('mousemove', mousemove);
    $document.off('mouseup', mouseup);
  }
}

但这仅适用于单个事件。

Angular 的示例使用 mousedown 添加 mousemove 和 mouseup 事件侦听器,this stackoverflow answer 使用 triggerHandler-- 防止冒泡/传播。

现在我有(大致):

describe('on mousedown it', function(){
  it('moves a thing', function(){
    expect(scope.x).toBe(0);
    element.triggerHandler({type: 'mousedown', pageX: 0, pageY:0});
    element.triggerHandler({type: 'mousemove', pageX:10, pageY:10);
    expect(scope.x).toBe(10);
  });
});

测试失败。 scope.x 记录为 0。 做什么?

【问题讨论】:

  • fwiw 在 $document 上触发处理程序也不起作用

标签: angularjs unit-testing angularjs-directive jasmine


【解决方案1】:

好吧,我看这个的方式,在示例中,拖动代码在指令中。因此,在查看测试时,因为指令正在操作指令所附加到的元素的位置,所以我会断言元素位置的变化,而不是断言内部范围变量的值。

假设我们有一个名为 myDraggable 的指令,它在测试时像 <span my-draggable="">Drag Me</span> 一样应用:

  1. 让我们编译指令。

    var scope = $rootScope.$new(); var elem = $compile('<span my-draggable="">Drag Me</span>')(scope);

  2. 然后将鼠标按下事件发送到编译元素

    elem.triggerHandler({type: 'mousedown', pageX: 0, pageY:0});

  3. 之后,因为鼠标移动事件附加到$document,让我们发送鼠标移动事件到$document

    $document.triggerHandler({type: 'mousemove', pageX: 10, pageY:20});

  4. 最后,让我们断言编译元素的最终位置

    expect(elem.css('top')).toBe('20px') expect(elem.css('left')).toBe('10px')

当我们把它们放在一起时,

describe('on mousedown it', function(){
  beforeEach(module('dragModule'));

  it('moves a thing', inject(function($compile, $rootScope, $document){
    var scope = $rootScope.$new();
    var elem = $compile('<span my-draggable="">Drag Me</span>')(scope);
    $rootScope.$digest();

    elem.triggerHandler({type: 'mousedown', pageX: 0, pageY:0});
    $document.triggerHandler({type: 'mousemove', pageX: 10, pageY:20});

    expect(elem.css('top')).toBe('20px');
    expect(elem.css('left')).toBe('10px');
  }));
});

这里是关于测试指令推荐方式的官方 Angular 文档:https://docs.angularjs.org/guide/unit-testing#testing-directives

这是实现我刚才谈到的所有内容的 plunker:https://plnkr.co/edit/QgWiVlbNOKkhn6wkGxUK?p=preview

【讨论】:

  • 你的回答真的帮了我:) 虽然我在 Angular 4 中实现它,但我真的从你的回答中得到了如何实现它的想法。非常感谢:)
【解决方案2】:

您也可以为 scope.x 测试/断言,但请考虑 Chanthu 的上述回答 - 使用范围编译指令的方式。

除此之外,您的测试失败的原因是除了 mousedown 之外的所有事件都在文档上触发,这与您的测试用例描述的不同。

尝试以下 sn-p:

                       describe('on mousedown it', function(){
                        it('moves a thing', function(){
                         expect(scope.x).toBe(0);
                         element.triggerHandler({type: 'mousedown',           
                         pageX: 0, pageY:0});
                         document.triggerHandler({type: 'mousemove', 
                         pageX:10, pageY:10);
                         expect(scope.x).toBe(10);
                        });
                      });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多