Testing Code Within Addeventhandler
Solution 1:
You can use window.dispatchEvent(new Event("orientationchange"))
directly instead of
event = document.createEvent("HTMLEvents");
event.initEvent("orientationchange", true, true);
Solution 2:
orientationchange
event listener can be tested with
window.dispatchEvent(newEvent('orientationchange'));
The problem is this is functional test, not unit test. Usually this kind of things is tested in E2E tests, this is the place where we want to check that the application plays nicely with browser and real DOM. Also, anonymous listeners cannot be removed, they may affect subsequent test and cause memory leaks.
A proper strategy for unit testing is to test written code line by line. Angular guide is specific on test isolation:
However, it's often more productive to explore the inner logic of application classes with isolated unit tests that don't depend upon Angular. Such tests are often smaller and easier to read, write, and maintain.
To be test-friendly the class can be refactored to
exportconstWINDOW = newOpaqueToken();
... providers: [..., { provide: WINDOW, useFactory: () =>window }];
exportclassAvailabilityComponent {
changed: boolean = false;
constructor(@Inject(WINDOW) window: Window) {
window.addEventListener( "orientationchange", this.orientationChangeListener);
}
orientationChangeListener = () => {
this.changed = !this.changed;
}
}
So it can be easily tested with
const windowMock = jasmine.createSpyObj(['addEventListener']);
const comp = new AvailabilityComponent(windowMock);
expect(windowMock.addEventListener).toHaveBeenCalledWith("orientationchange",
comp.orientationChangeListener);
expect(comp.changed).toBe(false);
comp.orientationChangeListener.call(null); // unbind methodexpect(comp.changed).toBe(true);
There is builtin DOCUMENT
service already, and WINDOW
service follows the same way, the recipe similar to $window
in AngularJS. Acting on the mocked service allows to provide isolation for unit test and not pollute global scope with changes that have to be cleaned up in afterEach
.
Since AvailabilityComponent
is a component and will be tested with TestBed anyway, it probably makes sense to incorporate the test into TestBed. See also this answer on isolated vs TestBed unit tests.
Solution 3:
I have managed to this working with the following -
it( 'expect orientationchange to update changed to be truthy', () => {
event = new Event('orientationchange');
component.ngOnInit();
window.dispatchEvent(event);
// ...
});
Post a Comment for "Testing Code Within Addeventhandler"