6

I'm tring to test a component class, but, my test won't work.

This is the part of stack error:

Error: Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed, got: [AlertModaldataComponent, [object Object], [object Object], ?[object Object]?, ...] in http://localhost:9878/_karma_webpack_/main.bundle.js (line 94300)
_reportError@http://localhost:9878/_karma_webpack_/main.bundle.js:94300:24
http://localhost:9878/_karma_webpack_/main.bundle.js:94095:39
forEach@[native code]
_getProvidersMetadata@http://localhost:9878/_karma_webpack_/main.bundle.js:94063:26

This is my component class

import { Component, OnInit, ViewChildren, QueryList, OnDestroy } from '@angular/core';
    import { MatMenuTrigger } from '@angular/material';
    import { Router } from '@angular/router';
    import { RefreshOnActionService } from './../../../services/refresh-on-action.service';
    import { AlertModaldataComponent } from './../../common/modal/alert-modaldata.component';
    import { RefreshEntityEnum } from './../../../shared/models/refresh-entity-enum';
    import { RefreshService } from './../../../services/refresh.service';
    import { AppService } from '../../../services/app.service';
    import { setInterval, clearInterval } from 'timers';
    import { StatusRefreshEnum } from '../../../shared/models/status-refresh-enum';

    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.scss']
    })
    export class HeaderComponent implements OnInit, OnDestroy {
      loggedUserId;
      showHeader = true;
      isLoading: boolean;
      isAdmin = false;
      menuItens: Array<any> = [];
      refreshId: number;
      balloon = false;
      balloonItens = 0;
      second = '00';
      minute = '00';
      hour = '00';
      timerZeroed = true;
      updatingList = false;
      getItemsQuantityInterval: any;
      private timer: any = null;

      constructor(
        private appService: AppService,
        private refreshService: RefreshService,
        private modal: AlertModaldataComponent,
        private router: Router,
        private refreshOnActionService: RefreshOnActionService
      ) {
        ...
      }

      @ViewChildren(MatMenuTrigger) trigger: QueryList<MatMenuTrigger>;

      ngOnInit() {
        ...
      }

      ngOnDestroy() {
        ...
      }

      refreshMenuItems(): void {
        ...
      }

      refreshBalloonInfo() { 
        ...
      }

      startTimer(): void {
        ...
      }

      activateSetTimeIntervalForItemsQuantity() {
        ...
      }

      openMatMenu() {
        ...
      }

      closeMatMenu() {
        ...
      }

      itemView(itemKey: any, type: RefreshEntityEnum, status: StatusRefreshEnum) {
        ...
      }

      timing(timestamp: number) {
        ...
      }

      aprove() {
        ...
      }
    }

And this is my spec class...

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router';

import { RefreshOnActionService } from './../../../services/refresh-on-action.service';
import { RefreshService } from './../../../services/refresh.service';
import { CommonOsgComponentsModule } from './../../common/common-osg-components.module';
import AppServiceStub from '../../../shared/testStubs/app-stub.service';
import RefreshServiceStub from '../../../shared/testStubs/refreshService-stub';
import { AppService } from '../../../services/app.service';
import { setCssTransformAsValidForPhantomBrowser } from '../../../shared/helpers';
import { HeaderComponent } from './header.component';
import { AngularMaterialModule } from '../../../angular-material/angular-material.module';
import RouterStub from '../../../shared/testStubs/router-stub';
import { RefreshEntityEnum } from '../../../shared/models/refresh-entity-enum';
import { StatusRefreshEnum } from '../../../shared/models/status-refresh-enum';
import { AlertModaldataComponent } from '../../common/modal/alert-modaldata.component';

fdescribe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;

  beforeEach(() => {
    setCssTransformAsValidForPhantomBrowser();
    TestBed.configureTestingModule({
      imports: [
        NoopAnimationsModule,
        AngularMaterialModule,
        CommonOsgComponentsModule
      ],
      declarations: [
        HeaderComponent
      ],
      providers: [
        AlertModaldataComponent,
        {
          provide: AppService,
          useClass: AppServiceStub
        },
        {
          provide: Router,
          useClass: RouterStub
        },
        {
          provider: RefreshService,
          useClass: RefreshServiceStub
        },
        {
          provide: RefreshOnActionService,
          useClass: RefreshOnActionService
        }
      ]
    });

    fixture = TestBed.createComponent(HeaderComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    const appService: AppService = TestBed.get(AppService);
    appService['_userData'] = 'x195363';
    expect(component).toBeTruthy();

  });

});

Every time that I run the tests, the error occours. Always the same error. I tried to find DynamicTestModule on my project but it doesn't exists and I don't know how to debug or resolve this. Someone can help me?

Vagner Leitte
  • 861
  • 7
  • 12
  • This has nothing to do with your question, but you could modify your `tsconfig.json` file so that your imports can be shortened. Add options in `compilerOptions.paths` that map to your app so you can do things like `import { Foo } from 'core'`, etc., instead of `import { Foo } from '../../../../core'` – Lansana Camara Apr 12 '18 at 17:47
  • I wonder if maybe it has something to do with testing things outside of the scope of what you're trying to exercise in this test. You're pulling in the entirety of Material for a test. Unless you're testing the output of the rendered content it seems a little much. Could you drop Material and instead put `schemas: [NO_ERRORS_SCHEMA],` in your testbed config. It will help narrow down where the error is coming from. It may also allow you to stop importing `CommonOsgComponentsModule` – zmanc Apr 12 '18 at 17:54

3 Answers3

2

In my case, after delete the file and re-create a new file with the same content, everything works fine. I don't know whats happened but, I imagine that some bits of infomation can be corrupted on original file.

Vagner Leitte
  • 861
  • 7
  • 12
  • could have been a misspelling, see also https://stackoverflow.com/questions/41980219/invalid-provider-for-the-ngmodule-dynamictestmodule-when-testing-a-service-in – mruanova Aug 20 '18 at 20:33
2

use

provide: RefreshService,
useClass: RefreshServiceStub

Instead of

provider: RefreshService,
useClass: RefreshServiceStub
Chromeium
  • 264
  • 1
  • 11
2

I also got this same error for one of my components which is expecting route data to initialize the component. Error is gone away after adding RouterTestingModule to the configureTestingModule in the .spec file.

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ InitiativeComponent],
      imports: [RouterTestingModule],
      providers: [ RouterTestingModule],
    })
    .compileComponents();
 }));

Hope this helpful for someone.

Malith
  • 506
  • 5
  • 9