Maus94
Maus94

Reputation: 51

Angular 2 - Unit testing service with Window dependency

I'm trying to test a service in Angular2. In the service, I'm using window.location and window.location.hash several times. After reading some other questions on Stackoverflow, I've decided to inject window in the service rather than using the global window directly.

@Injectable()
export class AuthService {
    constructor(private router: Router, private window: Window) { }
}

For that I've registered window in app.module.ts:

providers: [
           AuthService,
           {
               provide: Window,
               useValue: window
           },
           OtherService
 ]

Now in my test, I'm trying to mock window in a similar way to this answer: https://stackoverflow.com/a/37176904

beforeEach(() => {
routerStub = {
  navigate: jasmine.createSpy('navigate')
};
mockWindow = <any> { location: <any> {hash: 'testhash'}};
TestBed.configureTestingModule({
  providers: [
    AuthService,
    { provide: Router, useValue: routerStub },
    { provide: Window, useValue: mockWindow }
  ]
});

authService = TestBed.get(AuthService);
});

The error I get is the following: 'Error: Can't resolve all parameters for AuthService: ([object Object], ?)'

So while injecting a mock router works perfectly fine, injecting a mock window doesn't seem to work. Can anyone help me with this? Is there anything I'm doing wrong? I haven't been able to find a solution that works for me.

Upvotes: 5

Views: 3409

Answers (1)

Marcel Tinner
Marcel Tinner

Reputation: 1449

Try it like this

In your Service:

constructor(http: Http, @Inject('Window') private window: Window) {
        super(http);
        console.log(window.location);
    }

In your Module where you provide your Service, provide the window like this:

providers: [AuthService,{ provide: 'Window', useValue: window }, OtherService]

Then in your Test:

...
mockWindow = { location: {hash: 'testhash'}};
TestBed.configureTestingModule({
  providers: [
    AuthService,
    { provide: Router, useValue: routerStub },
   { provide: 'Window', useValue: mockWindow },

  ]
});
...

But take care, there ist an open bug for AoT https://github.com/angular/angular/issues/15640

Upvotes: 3

Related Questions