Component Testing: Routing Components (DRAFT) 4.0
- Component testing
- Running component tests
- Writing component tests
This page describes how to test routing components using real or mock routers. Whether or not you mock the router will, among other reasons, depend on the following:
- The degree to which you wish test your component in isolation
- The effort you are willing to invest in coding mock router behavior for your particular tests
This page uses the heroes app from part 5 of the tutorial as a running example. The app component of that revision of the app is just a shell delegating functionality to either the dashboard or heroes components.
The sample tests for each of these components have been written in a complementary manner: the heroes component tests use a mock router, whereas those for the dashboard use a real router.
Testing router links using a mock router
In test code excerpt given below, you can see the declaration of a
MockRouter class, and a
mockRouter instance. As described in the section on
Component-external services: mock or real
you must add the mock router to the providers list of the
Selecting a hero from the heroes list causes a “mini detail” view to appear:
Clicking the “View Details” button should cause a request to navigate to the
corresponding hero’s detail view.
The button’s click event is bound to the
gotoDetail() method which is defined as follows:
You could test for this behavior by ensuring that the mock router receives
Router.navigate() request with the appropriate link parameter list.
In the following test excerpt:
setUp()method selects a hero.
- The test expects a single call to the mock router’s
navigate()method, with the “HeroDetail” route as destination and the target hero’s id as a parameter.
Tests written using a mock router, embody significant detail concerning the router’s API, and expected argument values such as link parameter lists.
How might you write the same test using a real router? That’s covered next.
Test router links using a real router
One way to test using a real router is to mock the low-level PlatformLocation class. In addition to providing a mock platform location object, the real router expects the injector to supply values for:
- The ROUTER_PROVIDERS, some of which you’ll be overriding
APP_BASE_HREF, whose value is usually derived from the
<base href>element in the app’s
- ROUTER_PRIMARY_COMPONENT, identifying, as the name implies, the component to which the router is bound to.
The router queries the platform location for location properties such as path and search parameters. Initialize these appropriately for your app. In the case of the heroes app, these are initialized to the empty string using Mockito.when().thenReturn() calls.
Using this setup, the go-to-detail test illustrated in the previous section, could be written for the dashboard component as follows:
Contrast this with the heroes “go to details” test shown earlier. While the dashboard test requires lower-level configuration of a mock location, the test has the advantage of ensuring that route configurations are declared as expected.
Which routing components can I test?
You can test any routing component, except the app root (usually
This is because there is a circular dependency between the router
associated with the app root, and the app root instance itself.
In the context of a real app, the
cyclic dependency is resolved by bootstrapping, but such
a capability isn’t provided by
angular_test, nor is it generally needed
in the context of component testing.
When the app root is a routing component, it is often only an app shell,
delegating most of the work to other components. In such a case, it is these other components
which will be the most useful test subjects.