Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 8 test with Karma / Jasmine -> 100% code coverage not covered for loadChildren in angular routes

After upgrading from angular 7 to 8, there were breaking changes in loadChildren for your application routes. When these are fixed and all test are running, i don't get a 100% code coverage (anymore), because the loadChildren isn't a 'string' anymore, but a LoadChildrenCallBack.

How do i test this particulary part of code

setup:

import { NgModule } from '@angular/core';
import { RouterModule, RouterStateSnapshot, Routes } from '@angular/router';
import {
    RouterStateSerializer,
    StoreRouterConnectingModule,
} from '@ngrx/router-store';

import { LanguageGuard } from '@routes/guards/language-guard.service';
import { RouterStateUrl } from 'interfaces';
import { ErrorPageComponent } from 'pages';

/**
 * Class to implements the RouterStateSerializer with a custom serializer
 */
export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
    /**
     * Serialize the RouterState with the CustomSerialzer
     * @param {RouterStateSnapshot} routerState
     * @returns RouterStateUrl
     */
    serialize(routerState: RouterStateSnapshot): RouterStateUrl {
        let route = routerState.root;
        while (route.firstChild) {
            route = route.firstChild;
        }
        const {
            url,
            root: { queryParams },
        } = routerState;
        const { params } = route;
        return { url, params, queryParams };
    }
}

const appRoutes: Routes = [
    {
        children: [
            {
                path: '',
                pathMatch: 'prefix',
                redirectTo: 'en',
            },
            {
                component: ErrorPageComponent,
                path: '404',
            },
            {
                canActivate: [LanguageGuard],
                children: [
                    {
                        loadChildren: () =>
                            import('../modules/home.module').then(
                                m => m.HomeModule,
                            ),
                        path: '',
                        pathMatch: 'full',
                    },
                ],
                path: ':language',
            },
        ],
        path: '',
        runGuardsAndResolvers: 'always',
    },
];

/**
 * Marks an class as an NgModule so it could be configured
 */
@NgModule({
    exports: [RouterModule],
    imports: [
        RouterModule.forRoot(appRoutes, {
            enableTracing: false,
            onSameUrlNavigation: 'reload',
        }),
        StoreRouterConnectingModule.forRoot({
            serializer: CustomSerializer,
        }),
    ],
    providers: [{ provide: RouterStateSerializer, useClass: CustomSerializer }],
})

/**
 * Exports the AppRoutingModule from the NgModule
 */
export class AppRoutingModule {}
like image 617
rvdm Avatar asked Nov 07 '22 16:11

rvdm


1 Answers

In your spec.ts file

import { YourModule } from '....'

let router: Router;

beforeEach(async(() => {
   TestBed.configureTestingModule({
       // You need to config your TestBed and load any dependencies that are required by your Module.
       imports: [<more-here>, RouterTestingModule, <more-here>]
   });

   router = TestBed.get(Router);

}));

describe('Route XXXXX', () => {
   it('should load specific module', async () => {
       // locate the route config you are after
       // could be in the main config or in children or children of children
       const route = router.config[0].children.find(rc => rc.path === '<DESIRED_PATH>');
       // you can also make this an expectation...
       if (typeof route.loadChildren === 'function') {
           expect(await route.loadChildren()).toEqual(YourModule)
       }

   });
});
like image 106
GKA Avatar answered Nov 11 '22 12:11

GKA