Invalid provider for the NgModule 'DynamicTestModule' when testing a service in Angular 2
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') } },
Related videos on Youtube
Cristian
Updated on July 09, 2022Comments
-
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
So why do I have these errors? And what is the solution for the test to work?
-
AhmedRiyad about 7 yearsDo you have any dependency in ItemListService ?
-
Cristian about 7 yearsNo I don't have, but I found the issue. Check out the answer I have made.
-
-
Fallenreaper over 4 yearsand 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 toprovide
-
nilsandrey over 3 yearsNice catch, just for being explicit I add the correct syntax:
providers: [{provide: ApplicationActions, useClass: ActionMock}]
orproviders: [{provide: ApplicationActions, useValue: actionMockInstance}]
-
dataphile about 3 yearsIt's
provide
notprovider
-
Kirk Sefchik over 2 yearsThis response is not useful.
-
usalin over 2 yearsI had this error because of an extra comma.