Testing Angular Router Navigation
Introduction
If you are not too familiar with unit testing an Angular application, it may be a bit confusing to test a function that is utilizing an injected service, like Router
for example. Any non-trivial Angular application will include routing so this is a good one to look at.
In this post, we will show you perhaps the simplest way to unit test your navigation. This solution also works in other places where you are using an injected service.
Code Under Test
Let's look at where we are utilizing router navigation within a function inside of a component:

navigate
is the function we are going to be testing.
Approach
Since this is a unit test, all we want to do is make sure that the underlying service method gets called with the right input.
So what’s the simplest thing we can do to get unit test coverage on this function?
The answer is use a spy to replace our dependency. Spies are built-in to Jasmine, and Angular gives us an easy way to use a different value for an injected provider - so this is all pretty simple.
Let’s see how this is done:

The important parts are:
- Creating our spy for
Router
that replaces thenavigate
method we are invoking in the component method:
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
- Letting TestBed know we have a Router dependency, and that we are going to substitute it with our spy:
providers: [
{
provide: Router, useValue: routerSpy
}
]
- Invoke our component method in a test to check that the
Router
service method will be called:
// Get an instance of our spy-replaced Router:
const router = TestBed.inject(Router);
component.navigate('schedule');
expect(router.navigate).toHaveBeenCalledOnceWith(['schedule']);
Conclusion
Through this we can see how dependency injection lends itself to easy testing. We can replace our service dependencies with spies, and make sure they are getting called when and how they should be. Router
just happens to be a good example of this, being a commonly used dependency.