2

I'm facing some problems with unit testing for routing. I've tried this solution, but this lazy loading notation is now deprecated, so my tests are failed for some reason. Could someone give me advice what might be wrong with my code?

app-routing.module.ts:

export const routes: Routes = [
{path: 'about', component: AboutComponent},
{path: 'files', loadChildren: () => import('./files/files.module').then(m => m.FilesModule)}, 
];

@NgModule({
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
})
export class AppRoutingModule { }

app-routing.module.spec.ts:

describe('AppRoutingModule', () => {
   let location: Location;
   let router: Router;
   let fixture;

   beforeEach(() => {
   TestBed.configureTestingModule({
       imports:[
           RouterTestingModule.withRoutes(routes),
           HttpClientModule,
           AboutComponent,
       ],
       declarations: [
           AppComponent,
           FilesComponent,
       ],
       providers: [{provide: APP_BASE_HREF, useValue: '/'}]
   })

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

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

   it('should navigate to files', fakeAsync(() => {
       const loader = TestBed.get(NgModuleFactoryLoader);
       loader.stubbedModules = {lazyModule : FilesModule }

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

       router.navigate(['files']);
       tick(50);
       fixture.detectChanges();

       expect(location.path()).toBe('/files');
   }));
});

Thank you!

dancingsushi
  • 47
  • 1
  • 5
  • Your `app-routing.module.ts` consists of only two things: the routes and the initialization of the `RouterModule`. You override both in your test file. So what aspect of the original implementation are you actually testing? As far as I can see, this unit test only tests itself. – georg-un Sep 09 '22 at 06:10

2 Answers2

1

Did you try:

router.resetConfig([
  { path: 'files', loadChildren: () => Promise.resolve(FilesModule) },
 ]);

?

Or at this point it could be just an spy

const spy = jasmine.createSpy('loadChildren');
...
router.resetConfig([
  { path: 'files', loadChildren: spy  },
 ]);
...
expect(spy).toHaveBeenCalled();

Not tested to so no idea if it will work.

Xesenix
  • 2,418
  • 15
  • 30
  • 1
    This unfortunately does not work. To be more precisely, test seems to be passed, but it's not visible in coverage – dancingsushi Feb 18 '20 at 08:57
  • It depends what do you want to see in coverage. This only describes how to mock routing for unit tests. If you want integration test its better to cover that at e2e level. – Xesenix Aug 20 '20 at 20:23
  • Its just that the karma code coverage complaints that the imports are not covered in the tests. Therefor the same is shown in my sonarqube reports. – julianalimin Aug 21 '20 at 16:52
  • did you try to filter routing files from unit testing? Like adding some filtering here: ``` context.keys().forEach(require.context('../', true, /^\.[\/\\](app|somsubapp).*\.spec\.ts$/));``` – Xesenix Aug 21 '20 at 19:58
  • But then my Auth Guards would also be filtered, right ? – julianalimin Aug 21 '20 at 23:58
  • You probably have separate specs for your auth guards that should have test for them and also provide code coverage for them. If you set up guards inside routing testing module they should be covered if they are in the main route before loading mocked `load children`. If you have set them up in child module you probably need separate test for routing of that child module routing if you really want to test routing inside unit tests. So if you really need to test correct setup for routing you probably should use protractor for testing if user with correct acces rights can acces specific routes – Xesenix Aug 22 '20 at 00:35
  • I took another stab at it and got it working using the answer from here https://stackoverflow.com/a/61085452/3227392 – julianalimin Aug 24 '20 at 10:09
  • you may want to use https://github.com/getsaf/shallow-render if you want to use mostly same testing module setup that you use for your application – Xesenix Aug 24 '20 at 10:33
0

You can use SpyNgModuleFactoryLoader in place of NgModuleFactoryLoader.

const loader = TestBed.get(SpyNgModuleFactoryLoader);
   loader.stubbedModules = {lazyModule : FilesModule }
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
arshi
  • 1