Angular testing Service method with window.location.replace
Asked Answered
R

1

1

In my Angular 4 application, I need to test a method of a Service which at some point it calls a private method of the same service having:

window.location.replace(url);

When the test reach that line, the karma-runner browser gets redirected to the url which of course is not what I want.

If I try to spy it, I get:

Error: <spyOn> : replace is not declared writable or has no setter

How can I correctly test my method?

Recapture answered 28/8, 2017 at 19:49 Comment(2)
I'd move any reference to the window into a separate service, which should be trivial and which you can then mock elsewhere.Phil
Possible duplicate of Angular2 - How to inject window into an angular2 serviceCaning
D
2

location object is read-only property, and its properties are read-only as well.

The best test-friendly strategy is to not use native objects directly but via DI, because testabiliry is one of main benefits of DI.

document already has DOCUMENT provider abstraction, the same can be done for window entirely, similarly to AngularJS $window service:

const WINDOW = new InjectionToken('window');
function getWindow() {
  return window;
}

...
{ provide: WINDOW, useFactory: getWindow }
...

...
constructor(@Inject(WINDOW) public window) {
  this.window.location.replace(...);
}
...

In this setup WINDOW provider can be stubbed in tests, and globals can be thoroughly tested.

Alternatively, providers can be created for each global in use.

Dagenham answered 28/8, 2017 at 20:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.