5

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.

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. Commented Jun 27, 2017 at 12:42
  • Can't I just provide a mock window the way I'm doing it in the code above? Commented Jun 27, 2017 at 12:47

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.