6

I am using Angular2 (2.1.0) final release.

I was importing all components via AppModule when unit testing using ...

beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AppModule],
      ...

However, this made test runs slow.

I am now listing only the components I need as follows ...

  beforeEach(async(() => {
    // noinspection JSUnusedGlobalSymbols
    TestBed.configureTestingModule({
      imports: [BrowserModule, FormsModule, HttpModule], // modules
      declarations: [
        // pipes
        AttributeCheckPipe,
        // directives
        // DatePickerDirective,
        ...

However, I have lots and lots of components and I am not sure which ones to import. The test output does not tell me which ones I need to import. It just simply passes (when I import them all) or fails (if I don't) but it doesn't tell me which ones are needed.

The error is an annoying / useless ..

invokeTask@node_modules/zone.js/dist/zone.min.js:1:36996
onInvokeTask@node_modules/zone.js/dist/proxy.min.js:1:2190
invokeTask@node_modules/zone.js/dist/zone.min.js:1:36939
runTask@node_modules/zone.js/dist/zone.min.js:1:31466
a@node_modules/zone.js/dist/zone.min.js:1:17818
g@node_modules/core-js/client/shim.min.js:8:19058
node_modules/core-js/client/shim.min.js:8:19180
k@node_modules/core-js/client/shim.min.js:8:14294
l@node_modules/zone.js/dist/zone.min.js:1:18418
l@node_modules/zone.js/dist/zone.min.js:1:18175
node_modules/zone.js/dist/zone.min.js:1:18715

How do I get feedback about which components I failed to import? thx

I am using Karma and PhantomJS.

My Karma config excerpt is ..

client: {
  captureConsole: true
},
logLevel: config.LOG_DEBUG
danday74
  • 52,471
  • 49
  • 232
  • 283
  • To answer this question we would need to see your component and it's template – Paul Samsotha Oct 20 '16 at 16:01
  • ah ok i see why, you want to see what 'other' components / pipes, etc I import in the component I am testing? and what components I am using in the template? And what components those components are using too? Am I thinking on the right lines? Is there no easier way for the logs to just tell you what you forgot? – danday74 Oct 20 '16 at 16:06
  • 1
    Pretty much. Normally when you try to load a component and say your missing a directive in the test declaration, it will give you an error about template parsing it cant find binding for the element. Something like that. But generally you should already know what you need. You created the component and know what you used – Paul Samsotha Oct 20 '16 at 16:11
  • 1
    The one thing you _won't_ need is the `BrowserModule`. The test bed automatically imports the `CommonModule`, so you're set for common things like `*ngIf` and `*ngFor`, and common pipes. – Paul Samsotha Oct 20 '16 at 16:23
  • still struggling, zoneJs swallowing errors so I really have no idea what to do. I listed all components and successfully removed 1 or 2 but if i remove any others it causes failure – danday74 Oct 21 '16 at 11:09
  • finally managed to recover the swallowed error! – danday74 Oct 21 '16 at 13:28

1 Answers1

5

Finally made some progress here. I added a catch block to compileComponents() and logged e.message and got some useful output which gives me something to work on!

Heres my code ..

  beforeEach(async(() => {
    TestBed.configureTestingModule({

      imports: [FormsModule, HttpModule, routing], // modules

      declarations: [
        SaveSearchModalComponent
      ],
      providers: [
        ESQueryService,
        RESTQueryService,
      ]
    }).compileComponents()
      .then(() => {
        fix = TestBed.createComponent(SaveSearchModalComponent);
        instance = fix.componentInstance;
        injector = fix.debugElement.injector;
      }).catch((e) => {
      console.log(e.message);
      throw e;
    });
  }));

An excerpt from the error message output is ...

'dynamic-form' is not a known element: 1. If 'dynamic-form' is an Angular component, then verify that it is part of this module. 2. If 'dynamic-form' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message.

Amazing this is not covered anywhere in the docs (but I should have guessed this sooner!)

AND NOW WHAT ...

WOW, after doing the above (which fixed 99% of issues) I hit another useless error message ...

Component e is not part of any NgModule or the module has not been imported into your module.

Which comes from ...

/node_modules/@angular/compiler/bundles/compiler.umd.js

So following the advice at ..

Angular 2 Component is not part of any NgModule

I added this log statement to compiler.umd.js

// I ADDED THIS LOG STATEMENT
console.log('compType', String(compType));
// THIS LINE EXISTS ALREADY
throw new Error("Component " + stringify(compType) + " is not part of any NgModule or the module has not been imported into your module.");

this usually identifies the culprit. However, here I got the spurious output ...

LOG: 'function e(e) {__cov_m4LFTxiG42jWqZk7He0hiA.f['4']++;__cov_m4LFTxiG42jWqZk7He0hiA.s['11']++;this.router=e,this.formErrors={invalidCreds:!1};}'

which mentions this.router

So I removed the routing import and voila!

But unbelievable that this pain is necessary.

Community
  • 1
  • 1
danday74
  • 52,471
  • 49
  • 232
  • 283
  • 1
    Thanks for this. I was running into the same issue and spent way too much time trying to figure it out. Ultimately, I had to remove `AppModule` and my separate routing module, like you did, to get the tests to work, which is contrary to older posts on this subject. – occasl Nov 18 '16 at 19:05
  • these days I just import the module the component is in - then typically one or two other modules - e.g. routertestingmodule and sometimes httptestingmodule – danday74 Feb 21 '21 at 21:04