如何在Angular 2或4的Jasmine测试中模拟鼠标事件

Tum*_*ums 5 javascript unit-testing jasmine angular

我对Jasmine测试非常陌生,我正在尝试测试一个指令,该指令可以处理鼠标事件(例如,鼠标向下,向上和移动)。我的问题是如何从Jasmine规范中将鼠标坐标传递给我的指令并模拟鼠标事件。我已经在这个主题上进行了很多搜索,但是除了这个例子,我没有找到任何其他例子,例子没有像传递元素的坐标那样做任何事情。

以下是我尝试使用Angular中的TestBed配置编写测试的尝试:

import { Component, Directive, DebugElement } from "@angular/core";
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { By } from '@angular/platform-browser';
import { TestDirective } from "./test";
import { MyService } from "./my-service";

@Component({
    template: `<div testDirec style="height:800px; width:500px; background-color:blue;"></div>`
})
class DummyComponent { }

export default function () {
    describe('Directive: Zoom', () => {
        let fixture: ComponentFixture<TestComponent>;
        let debugEle: DebugElement[];

        beforeAll(() => {
          TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());

        }

        beforeEach(() => {
            TestBed.configureTestingModule({
                declarations: [TestDirective, DummyComponent],
                providers: [MyService]
            });
            fixture = TestBed.createComponent(DummyComponent);
            fixture.detectChanges();
            debugEle = fixture.debugElement.queryAll(By.directive(TestDirective));
        });

        it('mousedown on the div', () => {
            debugEle[0].triggerEventHandler('mousedown', null);
            expect(debugEle[0].nativeElement.style.width).toBe('500px');
        });

        it('mousemove on the div', () => {
            debugEle[0].triggerEventHandler('mousemove', null);
          expect(debugEle[0].nativeElement.style.backgroundColor).toBe('blue');
        });

    });

}
Run Code Online (Sandbox Code Playgroud)

我的指令如下:

import { Directive, ElementRef, HostListener} from "@angular/core";
import { MyService } from "./my-service";
@Directive({
    selector: "[testDirec]"
})
export class Test {
  private initPointX: number;
  private initPointY: number;

  constructor(private ele: ElementRef,
        private serviceInstance: MyService) {
    }

    @HostListener('mousedown', ['$event'])
    onMouseDown(event: MouseEvent) {
        console.log("Entered mouse down");
        this.initPointX = event.PageX;
        this.initPointY = event.PageY;
        if (event.ctrlKey) {
            // do something
        }
    } 

    @HostListener('mousedown', ['$event'])
    onMouseMove(event: MouseEvent) {
        console.log("Entered mouse move");
        if (this.initPointX && this.initPointY) {
            // calculate the new mouse x and y coordinates and compute the difference to move the object.
        }
    } 
 //other functions.

}
Run Code Online (Sandbox Code Playgroud)


正如您在测试规范中看到的那样,我将null作为事件传递。这将成功执行并运行我的测试,但我想通过从此处传递鼠标坐标来模拟鼠标事件。任何人都可以给我一些资源或为我指出正确的方向,如何实现这一目标,或者如果无法实现,我可以寻求什么替代方案。

任何帮助将不胜感激。

谢谢。
塔米·冈萨雷斯(Tammy Gonzalez)

小智 6

这应该比其他答案更具可读性:

const btn = btnDbg ? <HTMLButtonElement>btnDbg.nativeElement : new HTMLButtonElement();
btn.dispatchEvent(new Event('mousedown'));
Run Code Online (Sandbox Code Playgroud)


She*_*ero 3

我不明白你为什么要传递null你的triggerEventHandler. 相反,您应该传递一个对象。根据您的指令,该对象应该是pageX和事件pageY的值。mousedownmousemove

该指令将接收这些值并执行您的逻辑步骤,然后您就可以期待该值。您expect's当前拥有的没有任何意义,因为它们不测试与鼠标事件相关的任何内容。

我相信您正在寻找以下类型的规格:

it('mousedown on the div', inject([MyService], service) => {
     debugEle[0].triggerEventHandler('mousedown',{pageX:50, pageY: 40});
     debugEle[0].triggerEventHandler('mousemove',{pageX:60, pageY: 50});
     // assuming you are calculating the difference between the second and first objects.
     expect(service.someObj).toBe({x:10, y:10});
 });
Run Code Online (Sandbox Code Playgroud)

上面的代码很粗糙,但我希望它有帮助。

谢谢。