Unit Testing/mocking Window properties in Angular2 (TypeScript)

I’m building some unit tests for a service in Angular2.

Within my Service I have the following code:

var hash: string;
hash = this.window.location.hash;

However when I run a test which contains this code, it will fail.

It’d be great to utilise all the features of Window, but as I’m using PhantomJs, I don’t think this is possible (I have also tried Chrome which yields the same results).

In AngularJs, I would have resorted to mocking $Window (or at least the properties in question), but as there is not a lot of documentation for Angular2 unit testing I’m not sure how to do this.

Can anyone help?

3
Leave a Reply

avatar
3 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

In Angular 2 you can use the @Inject() function to inject the window object by naming it using a string token, like this constructor( @Inject('Window') private window: Window) { } In the @NgModule you must then provide it using the same string: @NgModule({ declarations: [ ... ], imports: [ ... ], providers: [ { provide: 'Window', useValue: window } ], }) export class AppModule { } Then you can also mock it using the token string beforeEach(() => { let windowMock: Window = <any>{ }; TestBed.configureTestingModule({ providers: [ ApiUriService, { provide: 'Window', useFactory: (() => { return windowMock; }) }… Read more »

Jason
Guest

As @estus mentioned in the comment, you’d be better getting the hash from the Router. But to answer your question directly, you need to inject window into the place you’re using it, so that during testing you can mock it. First, register window with the angular2 provider – probably somewhere global if you use this all over the place: import { provide } from '@angular/core'; provide(Window, { useValue: window }); This tells angular when the dependency injection asks for the type Window, it should return the global window. Now, in the place you’re using it, you inject this into your… Read more »

Jason
Guest

After RC4 method provide() its depracated, so the way to handle this after RC4 is:

  let myMockWindow: Window;

  beforeEach(() => {
    myMockWindow = <any> { location: <any> {hash: 'WAOW-MOCK-HASH'}};
    addProviders([SomeService, {provide: Window, useValue: myMockWindow}]);
  });

It take me a while to figure it out, how it works.