javascript - 如何从 Jasmine 测试 Angular 2/4 触发文档级事件

标签 javascript angular jasmine jasmine2.0

根据 Angular 测试文档,要从测试中触发事件,我们在调试元素上使用 triggerEventHandler() 方法。此方法采用事件名称对象。现在,如果我们使用 HostListener 添加事件,这将起作用。例如:@HostListener('mousemove', ['$event']) 或添加一个 document 级别的事件,我们这样做是这样的 @HostListener ('document:mousemove', ['$event']).

在我当前的指令实现中,由于我无法嵌套 HostListeners,我使用 document.addEventListener 添加 document 级事件到 HostListener.
代码如下:

@HostListener('mousedown', ['$event'])
callMouseDown(event){
  if (something) {
   document.addEventListener('mousemove', this.callMouseMove.bind(this));
  }
}

callMouseMove(event){
 // do some computations.
}

现在,我想触发在我的测试中添加到 document 级别的 mousemove 事件。 triggerEventHandler() 的当前实现不起作用,即在测试中未触发监听器。

我怎样才能让它发挥作用?谁能帮我一些指导。

编辑:添加测试:

it('test spec', inject([MyService], (service: MyService) =>{
   x = [];
  //service calls the method
  service.evtEmit.subscribe(e => {
   x.push(e);
  });
  triggerEventHandler("mousedown", {pageX: 200, pageY: 300});
  triggerEventHandler("document:mousemove", {pageX: 250, pageY: 320});
  // the above statement won't work.
  expect(arr).toEqual({x:50, y: 20});
}));

最佳答案

您描述的类似问题似乎已记录为问题 here在 Angular repo 上。

您可以使用组件实例访问指令并可以访问该方法(即,在您的情况下是 callMouseMove)。 以下方法应该有效:

it('test spec', inject([MyService], (service: MyService) => {
   x = [];
  //service calls the method
  service.evtEmit.subscribe(e => {
   x.push(e);
  });
  triggerEventHandler("mousedown", {pageX: 200, pageY: 300});
  component.directive.callMouseMove({pageX: 250, pageY: 320});
  expect(arr).toEqual({x:50, y: 20});
}));

希望这对您有所帮助。

更新

我意识到如果你的指令中有私有(private)方法,我的方法就不起作用了。最好以编程方式创建自定义事件或在这种情况下创建鼠标事件,并在文档级别或元素本身触发事件。 yurzui提到了这个方法.感谢他。

这里是你如何做到的:

function programmaticTrigger(eventType: string, evtObj: any) {
   let evt = new MouseEvent(eventType, evtObj);
   document.dispatchEvent(evt);
}

您可以从规范中调用此函数:

programmaticTrigger("mousemove", {clientX: 250, clientY: 320});

请注意,在这种情况下,我没有在此处传递 pageXpageY,因为它们是 readonly 但它们是基于内部计算的clientXclientY 值。

如果你想创建一个自定义事件并传入任何你想要的值,你可以这样做:

function programmaticTrigger(eventType: string, evtObj: any) {
       let evt: any;
       evt = Event(eventType, evtObj);
       document.dispatchEvent(evt);
    }

按如下方式调用它:

programmaticTrigger("mousemove", {pageX: 250, pageY: 320});

希望这对您有所帮助。

关于javascript - 如何从 Jasmine 测试 Angular 2/4 触发文档级事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45824452/

相关文章:

javascript - 如何在搜索栏中获取项目的详细信息?

angular - sidenav 生成已经声明结束的抽屉

javascript - 将查询结果存储在局部变量中并在 Angular 中发送相同的确认

javascript - 为什么我的 Jasmine 单元测试不等待 'done' ?

angularjs - 如何在 Angular 中正确模拟和测试 $window.variable?

javascript - 为什么 Internet Explorer 不能流畅地呈现此页面?

javascript - 为什么我的元素为空?

javascript - 在没有 viewModel 的情况下使用 ko.observable 数组

angular - 如何处理我的 "expression has changed after it has been checked error"特殊情况

javascript - Angularjs 单元测试未对来自 SELECT 节点的数据进行建模