Writing unit test cases for lazy loaded module angular

Viewed 492

Getting NgModuleFactoryLoader is deprecated: the string form of loadChildren is deprecated, and NgModuleFactoryLoader is part of its implementation. See LoadChildren for more details. warning and not able to stub the module for testing the lazy loaded module

Below is the code

import { Location } from '@angular/common';
    import { TestBed, ComponentFixture } from '@angular/core/testing';
    import { RouterTestingModule } from '@angular/router/testing';
    import { Router } from '@angular/router';
    import { AppComponent } from './app.component';
    import { AppConfigService } from './services/appConfig.service';
    import { TranslateModule } from '@ngx-translate/core';
    import { NgModuleFactoryLoader } from '@angular/core';
    import { VehicleModule} from './views/vehicle/vehicle.module';
    import { DriverModule} from './views/driver/driver.module';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

const routes: Routes = [{
    path: 'admin',
    data: { preload: false },
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  },
  { path: '', component: FrontpageComponent }];

    describe('Router: App', () => {

      let location: Location;
      let router: Router;
      let fixture: ComponentFixture<AppComponent>;
      let loader: any;

      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [
            BrowserAnimationsModule,
            TranslateModule.forRoot(),
            RouterTestingModule.withRoutes(routes),
          ],
          declarations: [AppComponent],
          providers: [AppConfigService]
        });

        router = TestBed.get(Router);
        location = TestBed.get(Location);

        loader = TestBed.get(NgModuleFactoryLoader);
        loader.stubbedModules = {
          'VehicleModule': VehicleModule,
          'DriverModule': DriverModule
        };

        fixture = TestBed.createComponent(AppComponent);

        router.resetConfig([
          {
            path: 'vehicle',
            loadChildren: 'VehicleModule'
          },
          {
            path: 'driver',
            loadChildren: 'DriverModule'
          },
          {
            path: '',
            loadChildren: 'VehicleModule'
          }
        ]);

        fixture = TestBed.createComponent(AppComponent);
        router.initialNavigation();
      });

      it('should create APP', () => {
        expect(fixture.componentInstance).toBeDefined();
      });

     it('should navigate to /student lazy loaded ,pdule', fakeAsync(() => {

        const loader = TestBed.get(NgModuleFactoryLoader);
        loader.stubbedModules = {lazyModule: StudentModule};

        router.resetConfig([
          {path: 'student', loadChildren: 'lazyModule'},
        ]);

        router.navigate(['student'])

        tick();

        expect(location.path()).toBe('/student');
      }));
    });
1 Answers

loadChildren now needs a function, which will load a module:

{
    path: 'login',
    loadChildren: () => import('./login/login.module').then(mdule=>mdule.LoginModule),

},

For some reasons, jasmine cannot load these modules from original config, so you should reset config and give to jasmine these modules:

    router.resetConfig([
      {
        path: 'vehicle',
        loadChildren: () => Promise.resolve(VehicleModule),
      },
      {
        path: 'driver',
        loadChildren: () => Promise.resolve(DriverModule),
      },
      {
        path: '',
        loadChildren: () => Promise.resolve(VehicleModule),
      }
    ]);

Also, you don't need NgModuleFactoryLoader more. Remove strings:

    loader = TestBed.get(NgModuleFactoryLoader);
    loader.stubbedModules = {
      'VehicleModule': VehicleModule,
      'DriverModule': DriverModule
    };

If you need guards (for example, you need to check if canActivate works as expected), you should keep original config, but all lazy loaded modules you need too:

    router.resetConfig([
      ...router.config,
      {
        path: 'vehicle',
        loadChildren: () => Promise.resolve(VehicleModule),
      },
      {
        path: 'driver',
        loadChildren: () => Promise.resolve(DriverModule),
      },
      {
        path: '',
        loadChildren: () => Promise.resolve(VehicleModule),
      }
    ]);
Related