测试角度mousedown,mousemove,mouseup

时间:2016-06-16 17:25:51

标签: angularjs unit-testing angularjs-directive jasmine

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。 怎么办?

2 个答案:

答案 0 :(得分:4)

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

鉴于我们有一个名为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')

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

    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');
      }));
    });
    

    以下是关于测试指令的推荐方法的官方角度文档:https://docs.angularjs.org/guide/unit-testing#testing-directives

    以下是实施我刚才谈到的所有事情的掠夺者:https://plnkr.co/edit/QgWiVlbNOKkhn6wkGxUK?p=preview

答案 1 :(得分:2)

你也可以测试/断言scope.x,但是请考虑Chanthu的上述答案 - 用范围编译指令的方法。

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

尝试以下代码段:

                       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);
                        });
                      });