How to simulate mouse events in Jasmine tests in Angular 2 or 4

百般思念 提交于 2019-12-10 14:34:49

问题


I am pretty new to Jasmine testing and I am trying to test a directive which handles mouse events like mouse down, up and move. My question is how can I pass mouse coordinates from the spec of Jasmine to my directive and simulate the mouse events. I have searched a lot on this topic but I couldn't find any examples except for this one which doesn't do anything like passing the coordinates of the element.

The following is my attempt to write the test using the TestBed configuration in Angular:

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

    });

}

My directive is as follows:

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.

}


As you can see inside my test spec, I am passing the null as the event. This will successfully execute and run my tests but instead I would like to simulate the mouse events by passing the mouse coordinates from here. Could anyone give me some resources or point me in a right direction how to achieve this or if it cannot be achieved what alternatives I can look into.

Any help would be greatly appreciated.

Thank you.
Tammy Gonzalez


回答1:


I don't understand why you are passing null in your triggerEventHandler. Instead you should be passing an object. According to your directive, the object should be pageX and pageY values for both the mousedown and the mousemove events.

The directive will receive these values and will execute the steps of your logic and then you can expect the value. The expect's which you have currently doesn't make any sense as they don't test anything related to the mouse events.

I believe the following type of spec is what you are looking for:

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

The above code is crude but I hope it's helpful.

Thanks.




回答2:


This should be more readable than the other answers:

const btn = btnDbg ? <HTMLButtonElement>btnDbg.nativeElement : new HTMLButtonElement();
btn.dispatchEvent(new Event('mousedown'));



回答3:


One thing, be sure if you're going to trigger a change in the DOM that you allow it to update. fixture.detectChanges() is your friend in that regard. In the tests, I see you click the element, but immediately check to see the change without allowing a detect changes to propagate up.



来源:https://stackoverflow.com/questions/44169580/how-to-simulate-mouse-events-in-jasmine-tests-in-angular-2-or-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!