2016-02-10 6 views
18

Ho un componente che utilizza un EventEmitter e EventEmitter viene utilizzato quando si fa clic su qualcuno sulla pagina. C'è un modo per osservare EventEmitter durante un test unitario e utilizzare TestComponentBuilder per fare clic sull'elemento che attiva il metodo EventEmitter.next() e vedere cosa è stato inviato?Un modo per testare EventEmitter in Angular2?

+0

Potete fornire una plunker che mostra quello che hai provato, allora posso avere uno sguardo per aggiungere i pezzi mancanti. –

risposta

48

Il test potrebbe essere:

it('should emit on click', inject([],() => { 
    tcb.createAsync(MyComponent) 
     .then((fixture) => { 
     // spy on event emitter 
     let component = fixture.componentInstance; 
     spyOn(component.myEventEmitter, 'emit'); 

     // trigger the click 
     let nativeElement = fixture.nativeElement; 
     let button = nativeElement.querySelector('button'); 
     button.dispatchEvent(new Event('click')); 

     fixture.detectChanges(); 

     expect(component.myEventEmitter.emit).toHaveBeenCalledWith('hello'); 
     }); 
})); 

quando il componente è:

@Component({ ... }) 
class MyComponent { 
    @Output myEventEmitter = new EventEmitter(); 

    buttonClick() { 
    this.myEventEmitter.emit('hello'); 
    } 
} 
+0

Se si tratta di un ancoraggio che si sta cliccando invece di un pulsante, il selettore di query dovrebbe essere solo un pulsante anziché? Sto usando qualcosa esattamente come quel componente, ma il 'expect (value) .toBe (' hello ');' non viene mai eseguito. Mi chiedo se sia perché è un'ancora invece. – tallkid24

+0

Ho aggiornato la mia risposta con un metodo più pulito per testare, usando una spia invece di un emettitore reale, e penso che dovrebbe funzionare (questo è quello che effettivamente faccio per i campioni nel mio ebook). – cexbrayat

+0

Questo funziona benissimo! Sono nuovo nello sviluppo front-end, in particolare l'unità che lo testa. Questo aiuta molto. Non sapevo nemmeno che esistesse la funzione spyOn. – tallkid24

1

È possibile iscriversi all'emettitore o associarvi ad esso, se è un @Output(), nel modello principale e controllare il componente principale se il collegamento è stato aggiornato. Puoi anche inviare un evento click e l'abbonamento dovrebbe attivarsi.

+0

Quindi, se mi è piaciuto emitter.subscribe (dati => { }); come ottenere l'output next()? – tallkid24

+0

Esattamente. Oppure il modello in 'TestComponent' ha' '(dove' someEmitter' è un '@Output()') quindi la proprietà 'value' di' TextComponent' dovrebbe essere aggiornato con l'evento inviato. –

4

Diciamo che avete un metodo chiamato buttonClick() che attiva un emettitore evento chiamato eventEmitter, è possibile iscriversi alla manifestazione e quindi chiamare il metodo per verificare se l'evento si attiva e chiamare il callback done() quando lo fa ...

@Component({ ... }) 
class MyComponent { 
    @Output eventEmitter = new EventEmitter(); 

    buttonClick() { 
     this.eventEmitter.emit('bar'); 
    } 
} 

E poi nel test ...

it('should emit on click', (done) => { 
    component.eventEmitter.subscribe(foo => { 
     expect(foo).toEqual('bar'); 
     done(); 
    }); 
    component.buttonClick(); 
}); 

In alternativa, è possibile utilizzare una spia, dipende dal vostro stile. Ecco come si usa una spia facilmente per vedere se emit che viene sparato fuori ...

it('should emit on click', fakeAsync(() => { 
    spyOn(component.eventEmitter, 'emit'); 
    component.buttonClick(); 
    tick(1); 
    expect(component.eventEmitter.emit).toHaveBeenCalled(); 
    expect(component.eventEmitter.emit).toHaveBeenCalledWith('bar'); 
}));