Home > Software engineering >  Angular: How to create a testing-module for a feature in an Angular app?
Angular: How to create a testing-module for a feature in an Angular app?

Time:11-07

I have a "normal" (nothing special about it) Angular app with some shared features. Since i want to avoid mocking these shared-features in component tests over and over I was thinking about introducing a test-module version of every feature. It should look like something like this:

SharedModule
 |
 |- drop-zone
 |   |_ (module contents skipped for brevity)
 |   |_ drop-zone.module.ts
 |   |_ drop-zone-testing.module.ts
 |
 |- other-features...
  • The drop-zone.module.ts should be an angular module, including all "prod / normal" declarations, services and so on.
  • The drop-zone-testing.module.ts should also include the "normal" declarations but fake services for example.

But when doing so, I get the Angular error when running ng build:

The Component 'FileDropZoneComponent' is declared by more than one NgModule.
- 'FileDropZoneComponent' is listed in the declarations of the NgModule 'FileDropTestingModule'.
- 'FileDropZoneComponent' is listed in the declarations of the NgModule 'FileDropModule'.

I already tried to remove all testing-module-files from the angular-build via pattern *testing.module.ts in tsconfig's exclude, but to no avail :/ I thought that excluding these modules from build should stop angular from complaining about two modules being present with the same declaration. But it does not work.

Does anyone have a solution how to create TestingModules for a custom feature in an Angular app?

CodePudding user response:

I figured out how to do it - but it seems like a workaround that does not even make too much sense to me :D But it works, both in tests and on build:

I should mention that in my solution I still removed the file, where I define my own decorator in via tsconfig.app.json:

{
   "exclude": ["src/**/testing/**/*"],
}
  1. Create your own decorator that simply wraps the NgModule decorator:
// e.g. src/shared/testing/utils.ts
export function NgTestingModule(obj: NgModule) {
  return NgModule(obj);
}
  1. use in your testing modules:
import { NgTestingModule } from '../testing/utils';

@NgTestingModule({ ... })
export class DropZoneTestingModule {}
  1. and in your tests:
TestBed.configureTestingModule({
  imports: [DropZoneTestingModule],
});
  • Related