Mocking @ngrx/router-store's selectRouteParam

1.8k Views Asked by At

I have an Angular 8 app (core 8.1.2) using NgRx and the @ngrx/router-store (8.4.0) but am having trouble mocking a selector generated by fromRouter.getSelectors(selectRouter).

The selector I have written and am trying to test looks like this:

export const selectFilteredPagedFeaturedPlaylists = createSelector(
  selectFilteredFeaturedPlaylists,
  selectRoutePageIndex,
  selectPageSize,
  (featuredPlaylists, pageIndex, pageSize) => ({
    ...featuredPlaylists,
    content: featuredPlaylists.content.slice(+pageIndex * pageSize, (+pageIndex + 1) * pageSize)
  })
);

and the selectRoutePageIndex selector, calling a method generated by the store, looks like this:

export const selectRoutePageIndex = selectRouteParam('pageIndex');

In reality, I am not necessarily concerned with mocking the selectRouteParam selector, but I need to mock my selectRoutePageIndex selector. Unfortunately, the technique described in the docs doesn't appear to work for selectors generated by @ngrx/router-store.

Any ideas how I can do this?

2

There are 2 best solutions below

0
On

I did not find an answer to my question, but I have created a workaround. I have wrapped the router store's selector in a createSelector() call and just returned it. It looks like this:

export const innerSelectRoutePageIndex = selectRouteParam('pageIndex');

export const selectRoutePageIndex = createSelector(
  innerSelectRoutePageIndex,
  (routePageIndex) => routePageIndex
);

So the client code still uses the selectRoutePageIndex selector, and MockStore.overrideSelector() is happy with the arrangement. It seems that createSelector() is more forgiving of the signatures of the selectors it is passed.

0
On

Just wanted to provide my solution in 2019. It's pretty similar to yours already. Here's how my selectors are setup for the router.

export const selectRouter = createSelector(
    (state: fromRoot.State) => state.router,
    value => value,
);

const {
    selectQueryParams, // select the current route query params
    selectQueryParam, // factory function to select a query param
    selectRouteParams, // select the current route params
    selectRouteParam, // factory function to select a route param
    selectRouteData, // select the current route data
    selectUrl, // select the current url
}: RouterStateSelectors<any> = fromRouter.getSelectors(selectRouter);

And then, in my test, I can mock out the router state like this.

mockStore.overrideSelector(fromCore.selectRouter, {
    state: {
        root: {
            params: {
                't': 'test', // query string parameter
            },
        },
    },
    navigationId: null,
});