Invalid provider for the NgModule 'DynamicTestModule' when testing a service in Angular 2

21,244

Solution 1

This is such an annoying error, thought I'd include another subtle cause to look for in your spec. In my case I specified providers instead of the correct value of provide as below

 TestBed.configureTestingModule({
      providers: [{provider: ApplicationActions, useClass: ActionMock}]

rather than offer useful information like "no 'provide' key specified" it simply reports

Failed: Invalid provider for the NgModule 'DynamicTestModule' - only instances of Provider and Type are allowed, got: [?[object Object]?, ...]

Solution 2

BTW also mind to use the class in providers, not some variable. This happened to me due to an accidental problematic replacement/casing:

Correct

 TestBed.configureTestingModule({
    // ...
    providers: [ SomeService ]
}

instead of...

Incorrect

 TestBed.configureTestingModule({
    // ...
    providers: [ someService ]
}

Note the camelCase variable (someService) is likely there if you use it in your test, that's why it does not throw a syntax error.

Solution 3

In my case, I had a stray comma in one of my provider lines, causing the DynamicTestModule to think I had passed an undefined definition.

        {
          provide: ApiService,
          useValue: {
            getUsers: jasmine
              .createSpy('getUsers')
              .and.returnValue(of({ status: 200, body: [] })),
          },
        },
        , // whoops!
        MessageService,
        { provide: Location, useValue: { back: jasmine.createSpy('back') } },
Share:
21,244

Related videos on Youtube

Cristian
Author by

Cristian

Updated on July 09, 2022

Comments

  • Cristian
    Cristian almost 2 years

    I have the following service:

    import { Injectable } from '@angular/core';
    
    import { MenuItem } from './../classes/menu-item';
    import { ITEMS } from './../static-data/items-list';
    
    @Injectable()
    export class ItemsListService {
    
        getItems(): Promise<MenuItem[]> {
            return Promise.resolve(ITEMS);
        }
    
    }
    

    The test for this service is here:

    import { TestBed, async, inject } from '@angular/core/testing';
    
    import { ItemListService } from './item-list.service';
    import { MenuItem } from './../classes/menu-item';
    import { ITEMS } from './../static-data/items-list';
    
    describe('ItemListService', () => {
      beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [ ItemListService, MenuItem, ITEMS ]
        });
      });
    
      it('should ...', inject([ItemListService], (service: ItemListService) => {
        expect(service).toBeTruthy();
      }));
    });
    

    The MenuItem is defined here:

    export class MenuItem {
        name: string;
        link: string;
    }
    

    ITEMS is defined here: import { MenuItem } from './../classes/menu-item';

    export var ITEMS: MenuItem[] = [
        {name: 'Vehicles', link: '/vehicles'},
        {name: 'Gateways', link: '/gateways'},
        {name: 'Statuses', link: '/statuses'},
        {name: 'Logs', link: '/logs'}
    ]
    

    When I run the test I am getting in the browsers console the followings errors:

    FAILED ItemListService should ...
    

    and

    enter image description here

    So why do I have these errors? And what is the solution for the test to work?

    • AhmedRiyad
      AhmedRiyad about 7 years
      Do you have any dependency in ItemListService ?
    • Cristian
      Cristian about 7 years
      No I don't have, but I found the issue. Check out the answer I have made.
  • Fallenreaper
    Fallenreaper over 4 years
    and Check spelling and capitalization explicitly. When I was looking into this issue, it was because I used a capital letter instead of lowercase. Provide as opposed to provide
  • nilsandrey
    nilsandrey over 3 years
    Nice catch, just for being explicit I add the correct syntax: providers: [{provide: ApplicationActions, useClass: ActionMock}] or providers: [{provide: ApplicationActions, useValue: actionMockInstance}]
  • dataphile
    dataphile about 3 years
    It's provide not provider
  • Kirk Sefchik
    Kirk Sefchik over 2 years
    This response is not useful.
  • usalin
    usalin over 2 years
    I had this error because of an extra comma.