2

I have an Angular (4.x) application with a top-level module AppModule, which declares several custom components, so they can be used in templates.

However, for jasmine/karma tests the most common approach seems to be using BrowserDynamicTestingModule and declare any required custom components during beforeEach, e.g.:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [ MyComponent, SomeDependedUponComponent ]
  })
  .compileComponents();
}));

Considering we're simulating the main application's environment anyway, why wouldn't one just initialize the testBed with AppModule, so every custom component is available to all tests? Something like:

getTestBed().initTestEnvironment(
  [BrowserDynamicTestingModule, AppModule],
  platformBrowserDynamicTesting()
);

If I'm not missing something, this is much closer to the main application's setup and even reduces boilerplate code in individual spec/test files. Orre there any disadvantages, such as a performance penalty?

Cedric Reichenbach
  • 8,970
  • 6
  • 54
  • 89

1 Answers1

3

The said approach is wrong because this way the tests are de facto integration tests, while they are supposed to be unit tests.

The purpose of unit test is to test a single unit. Adding additional moving parts prevents it from being tested in isolation and complicates trouble solving when one of the units fails. The isolation can be improved with isolated unit tests without TestBed, although TestBed is still necessary to test DI annotations.

This approach requires to provide integration/e2e tests as well to be sure that all units were properly tested in unit tests and can really interoperate.

If the specs result in boilerplate code, this can be further improved with proper setup, like is shown here.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Fair enough, I think I see the unit vs. integration test argument. However, it might still make sense to declare all components initially in the testing module, but without loading the whole `AppModule`, right? I mean declarations are only about availability, but should not affect functionality whatsoever. – Cedric Reichenbach Oct 13 '17 at 11:29
  • All these components and directives will be automatically compiled in tested components if their selectors are present in component template. And this is not something that is desirable in unit tests. You cannot mock providers in nested components, that's the problem. The best way to properly treat a situation like [this one](https://stackoverflow.com/q/46601574/3731501) is to not let it happen. – Estus Flask Oct 13 '17 at 11:43