Lets say I have a simple module AppModule
which has many imports, declarations and providers. Now I want to write a test for a component ListComponent
which is located in this module's declaration list. ListComponent
itself uses many, (but not every) import of the AppModule
. I do it like this:
import { TestBed } from '@angular/core/testing';
// +same copy-pasted list of imports from `AppModule`
beforeEach(done => {
TestBed.configureTestingModule({
imports: [
// +same copy-pasted list of imports from `AppModule`
],
declarations: [
// +same copy-pasted list of declarations from `AppModule`
],
providers: [
{
provide: Http,
useClass: HttpMock,
},
{
provide: Router,
useClass: RouterMock,
}
// +same copy-pasted list of providers from `AppModule`
]
});
It works, but surely it is an incorrect approach. I do not want to copy-paste so much. Maybe I can reuse the AppModule in some convenient approach? Pseudocode would be like:
let appModule = new AppModule();
beforeEach(done => {
TestBed.configureTestingModule({
imports: appModule.imports,
declarations: appModule.declarations,
providers: [...appModule.providers,
{
provide: Http,
useClass: HttpMock,
},
{
provide: Router,
useClass: RouterMock,
}
]
});
But I just do not know/cannot find the syntax for such approach :(
No problem! You can import the same module twice but Angular does not like modules with circular references and raise the circular dependency warnings on builds. Actually, the module helps you to organize an application into associative blocks of functionality.
TestBed is the primary api for writing unit tests for Angular applications and libraries. Note: Use TestBed in tests. It will be set to either TestBedViewEngine or TestBedRender3 according to the compiler used.
TestBed. configureTestingModule() helps you configure the providers. Configuring the providers means you are letting the Angular dependency injection system know about this dependency which later it can inject in to components when requested through a dependency injection token.
Sharing moduleslink You can put commonly used directives, pipes, and components into one module and then import just that module wherever you need it in other parts of your application.
You can create reusable const that contains the commom imports, providers from the modules you want.
for example in a app.providers.ts file you can have your providers like this:
import service1 from '.path/service/service1';
import service2 from '.path/service/service2';
export const providers = [service1, service2 ];
and for your imports in a app.imports.ts
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { Module1} from ''.path/service/module1';
export const imports= [
BrowserModule,
AppRoutingModule,
Module1
],
and on your app.module.ts and any other module you wanna use the same imports and providers you can do:
import { providers } from './app.providers';
import { imports } from './app.imports';
@NgModule({
declarations: [AppComponent],
imports: imports,
providers: providers,
bootstrap: [AppComponent]
})
You can also use the spread operator to add your unique imports to these shared imports on a specific module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With