I have a simple case. The standard AppComponent
of an Angular app contains a ChildComponent
which is defined in its own module ChildModule
.
The template of ChildComponent
is very simple
<div class="child" (click)="testClick($event)"></div>
ChildComponent
has an even simpler testClick(event)
method that just logs a message on the console.
testClick(event) {
console.log(event);
}
Now I want to build a test on AppComponent
simulating a click on ChildComponent
.
This is the code of the test
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let app: AppComponent;
let child: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ ChildModule ],
declarations: [
AppComponent
],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
app = fixture.debugElement.componentInstance;
child = fixture.debugElement.query(By.css('.child'));
fixture.detectChanges();
});
it(`should create the child'`, async(() => {
expect(child).toBeTruthy();
}));
it(`clicks on the child and the relative Observable emits`, async(() => {
setTimeout(() => {
child.triggerEventHandler('click', 'clicked');
}, 100);
}));
});
The tests work and in particular the second test prints the clicked
message on the console, as expected.
Now I complicate a bit ChildComponent
. I want to create an Observable on the click
event using the fromEvent
operator and ViewChild
.
So the code becomes
export class ChildComponent implements AfterViewInit {
@ViewChild('child') private childElement: ElementRef;
ngAfterViewInit() {
const testClick$ = fromEvent(this.childElement.nativeElement, 'click');
testClick$.subscribe(d => console.log('test click in child', d));
}
}
I launch the development server with ng serve
and I see 2 messages printed on the console, one by the testClick
method and one by the subscription of the testClick$
Observable.
If I run now the same tests as before, I expect to see also the same two messages printed on the console. On the contrary I see only the message printed by the testClick
method. The message of the subscription, i.e. 'test click in child'
, does not appear, which means that the Observable testClick$
does not emit when child.triggerEventHandler('click', 'clicked');
is executed.
How can I make Observables created with fromEvent
work in jasmine tests? What am I doing wrong?
Eventually I found a way to fire events that can be used within the fromEvent
function of RxJs.
The solution has been inspired by this post.
The idea is that in order to be able to create an event stream from a DOM event you have to use the method dispatchEvent
on the native element wrapped by the DebugElement.
So, rather than doing
child.triggerEventHandler('click', 'clicked');
you have to use something like
child.nativeElement.dispatchEvent(new MouseEvent('click', {...});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With