2017-08-22 3 views
3

Selon la documentation de Angular Testing, pour déclencher les événements à partir des tests, nous utilisons la méthode triggerEventHandler() sur l'élément de débogage. Cette méthode prend le event name et le object. Maintenant, cela fonctionne si nous ajoutons les événements en utilisant le HostListener. Par exemple: @HostListener('mousemove', ['$event']) ou pour ajouter un événement de niveau document, nous faisons quelque chose comme ceci @HostListener('document:mousemove', ['$event']).Comment déclencher des événements de niveau document à partir d'un test de jasmin Angular 2/4

Dans ma mise en œuvre actuelle de la directive, comme je ne peux pas imbriquer les HostListeners, j'ajouter les événements de niveau document utilisant le document.addEventListener dans un HostListener.
code est le suivant:

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

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

Maintenant, je veux déclencher l'événement mousemove qui est ajouté au niveau document de mes tests. L'implémentation actuelle de triggerEventHandler() ne fonctionne pas, c'est-à-dire que l'écouteur n'est pas déclenché dans le test.

Comment puis-je faire fonctionner cela? Quelqu'un pourrait-il m'aider avec quelques conseils.

Edit: Ajouté Test:

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

Est-ce que cette syntaxe 'this.callMouseMove()' est correcte? – yurzui

+0

Pouvez-vous également ajouter votre test? – yurzui

+0

@yurzui Bonjour, j'ai mis à jour le test. et j'ai fait une erreur dans la syntaxe d'appeler la fonction que je l'ai fixée maintenant. –

Répondre

3

On dirait que le même problème que vous avez décrit est enregistré comme la question here sur repo angulaire.

Vous pouvez obtenir l'accès de la directive à l'instance de composant et accéder à la méthode (c'est-à-dire, dans votre cas, c'est l'appelMouseMove). La façon suivante devrait fonctionner:

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

Hope this helps.

Mise à jour

je réalisais que mon chemin ne fonctionne pas si vous avez des méthodes privées à l'intérieur de votre directive. Il est préférable de créer des événements personnalisés ou, dans ce cas, un événement de souris par programmation et de déclencher les événements au niveau du document ou sur l'élément lui-même. Cette méthode a été mentionnée par yurzui. Grâce à lui.

Voilà comment vous pouvez le faire:

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

Vous pouvez appeler cette fonction de vos spécifications comme:

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

Notez que, je ne porte pas de pageX ou pageY ici dans ce cas, car ils sont readonly mais ils sont calculés en interne sur la base des valeurs clientX et clientY.

Si vous voulez créer un événement personnalisé et passer ce que les valeurs que vous voulez, vous pouvez le faire comme suit:

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

invoquons comme suit:

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

Hope this helps.

+1

Merci pour le lien et la réponse :) Cela a fonctionné. –