8

I want to import certain modules for all testing suits such as ngrx Store, ngx translate or httpClientModule in an angular-cli@1.50 project with angular 5.

in the generated test.ts I have added a test.configureTestingModule

const testBed: TestBed = getTestBed();

testBed.initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting()
);

testBed.configureTestingModule({
    imports: [
        HttpClientModule,
        StoreModule.forRoot(reducers, { metaReducers }),
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: (createTranslateLoader),
                deps: [HttpClient]
            }
        }),
    ]
}

Still in a user.servive.spec.ts it says no provider for Store.

user.service.spec.ts

describe('UserService', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [UserService]
        });
    });

    it('should be created', inject([UserService], (service: UserService) => {
        expect(service).toBeTruthy();
    }));
});

Does the Test.configureTestingModule in user.service.spec "overwrite" the one from test.ts?

If so, how can I configure the TestBed on a global level to avoid importing repetitive modules?

Thanks!

amphetamachine
  • 27,620
  • 12
  • 60
  • 72
Han Che
  • 8,239
  • 19
  • 70
  • 116
  • I don't have your userService, but I'm pretty sure the error is because you forgot to import the Store service in your testbed. What is the constructor of your userService ? –  Nov 09 '17 at 14:36
  • 1
    i didn't forget, i want to import and provide the store globally for all tests, that why i've imported it in test.ts – Han Che Nov 09 '17 at 14:49
  • Tests are made in one file and are not global (for all I know). If you want to 'make it global', you will have to make an utils file that is able to construct a testbed, then call it in a beforeEach in every file. –  Nov 09 '17 at 14:52
  • thats what some other blogs have hinted, but thanks for the clarification! – Han Che Nov 09 '17 at 15:06

3 Answers3

4

The short answer is that TestBed hooks into Jasmine's beforeEach and afterEach callbacks which resets the testing module between EVERY test. This gives you a clean-slate for each unit test.

This means that you cannot use TestBed.configureTestingModule inside your test.ts file. You must do it for each spec manually or write your own default test setup utilities to handle it.

I'm the dev for shallow-render which does have a solution for this by using Shallow.alwaysProvide() to globally setup/override/mock providers and forRooted providers in your test environment. The rest of your test module setup is handled by the library.

https://github.com/getsaf/shallow-render#global-providers-with-alwaysprovide

Hope this helps.

getsaf
  • 1,761
  • 1
  • 10
  • 8
1

The other answer covers the way configureTestingModule works before/after individual tests, but you don't necessarily have to use a plugin to have a simple "always provide" module setup. I created a paths alias in my testing tsconfig:

        "paths": {
            "@testing": ["src/testing/index"],
            "@testing/*": ["src/testing/*"]
        }

This lets me write a TestModule module with all the shared imports:

@NgModule({
  imports: [
    // All repeated modules
  ],
})
export class TestModule { }

Then, each call to configureTestingModule only needs to import { TestCommon } "@testing/test-common.module" and include it in the imports section of the test module config.

Coderer
  • 25,844
  • 28
  • 99
  • 154
0

There is no need to go for a separate library just to achieve this. You can create a global TestBed just by creating a common angular module where you can define a utility method. This utility method creates the TestBed which you can then reuse across all your spec files.

You can refer to the answer below which also includes sample code: https://stackoverflow.com/a/64835814/4184651

Evan MJ
  • 1,967
  • 13
  • 16