使用Karma / Jasmine进行Angular 8测试->覆盖100%的代码覆盖率(不包含load儿童)

时间:2019-06-08 08:47:26

标签: angular karma-jasmine angular-router

从角度7升级到8后,您的应用程序路由的loadChildren发生了重大变化。当这些问题修复并且所有测试都在运行时,我(不再)获得100%的代码覆盖率,因为loadChildren不再是“字符串”,而是LoadChildrenCallBack。

我如何测试代码的这一特殊部分

设置:

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 {}

1 个答案:

答案 0 :(得分:0)

在您的spec.ts文件中

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)
       }

   });
});