4

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.

Maus94
  • 41
  • 1
  • 2
  • Because the tests aren't run in a browser the window object will be undefined. Create a "Window" class that wraps your window functionality and checks for the existence of the window object. If it exists, return it otherwise return a mock window. – Stephen Wilson Jun 27 '17 at 12:42
  • Can't I just provide a mock window the way I'm doing it in the code above? – Maus94 Jun 27 '17 at 12:47

1 Answers1

3

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

Marcel Tinner
  • 1,343
  • 11
  • 18