angularangular-componentsangular-moduleangular-test

How to reuse all imports in Angular test files


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 :(


Solution

  • 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.