I'm trying to test a basic angular 2 component that Includes a service. When I run my test I'm getting the following errors. The component, service and test are pretty small, they run fine in the browser as well. I'm not sure what I am missing from the test in order for it to work.
Any help is appreciated.
Uncaught Error: Cannot set base providers because it has already been called(…)
Uncaught Error: Error in ./TestComponent class TestComponent - inline template:0:0 caused by: No provider for Http!
Error: No provider for Http!
at NoProviderError.BaseError [as constructor] (http://localhost:9876/base/karma-shim.js:4006:34)
at NoProviderError.AbstractProviderError [as constructor] (http://localhost:9876/base/karma-shim.js:33221:16)
at new NoProviderError (http://localhost:9876/base/karma-shim.js:33252:16)
at ReflectiveInjector_._throwOrNull (http://localhost:9876/base/karma-shim.js:57969:19)
at ReflectiveInjector_._getByKeyDefault (http://localhost:9876/base/karma-shim.js:57997:25)
at ReflectiveInjector_._getByKey (http://localhost:9876/base/karma-shim.js:57960:25)
at ReflectiveInjector_.get (http://localhost:9876/base/karma-shim.js:57769:21)
at TestBed.get (http://localhost:9876/base/karma-shim.js:5778:67)
at ElementInjector.get (http://localhost:9876/base/karma-shim.js:58133:48)
at _View_TestComponent0.createInternal (TestComponent.ngfactory.js:21:68)
at _View_TestComponent0.AppView.create (http://localhost:9876/base/karma-shim.js:58492:21)
at _View_TestComponent0.DebugAppView.create (http://localhost:9876/base/karma-shim.js:58704:44)
at _View_TestComponent_Host0.createInternal (TestComponent_Host.ngfactory.js:18:14)
at _View_TestComponent_Host0.AppView.create (http://localhost:9876/base/karma-shim.js:58492:21)
at _View_TestComponent_Host0.DebugAppView.create (http://localhost:9876/base/karma-shim.js:58704:44)
at ComponentFactory.create (http://localhost:9876/base/karma-shim.js:33751:36)
at initComponent (http://localhost:9876/base/karma-shim.js:5816:53)
at ZoneDelegate.invoke (http://localhost:9876/base/karma-shim.js:48531:26)
at ProxyZoneSpec.onInvoke (http://localhost:9876/base/karma-shim.js:48195:39)
at ZoneDelegate.invoke (http://localhost:9876/base/karma-shim.js:48530:32)
at Object.onInvoke (http://localhost:9876/base/karma-shim.js:22909:37)
at ZoneDelegate.invoke (http://localhost:9876/base/karma-shim.js:48530:32)
at Zone.run (http://localhost:9876/base/karma-shim.js:48413:43)
at NgZone.run (http://localhost:9876/base/karma-shim.js:22799:62)
at TestBed.createComponent (http://localhost:9876/base/karma-shim.js:5819:62)
at Function.TestBed.createComponent (http://localhost:9876/base/karma-shim.js:5634:33)
at Object.<anonymous> (http://localhost:9876/base/karma-shim.js:63273:41)
at ZoneDelegate.invoke (http://localhost:9876/base/karma-shim.js:48531:26)
at ProxyZoneSpec.onInvoke (http://localhost:9876/base/karma-shim.js:48195:39)
at ZoneDelegate.invoke (http://localhost:9876/base/karma-shim.js:48530:32)
at Zone.run (http://localhost:9876/base/karma-shim.js:48413:43)
at Object.<anonymous> (http://localhost:9876/base/karma-shim.js:47910:34)
at ZoneQueueRunner.jasmine.QueueRunner.ZoneQueueRunner.execute (http://localhost:9876/base/karma-shim.js:47940:42)
at ZoneQueueRunner.jasmine.QueueRunner.ZoneQueueRunner.execute (http://localhost:9876/base/karma-shim.js:47940:42)
at ZoneDelegate.invokeTask (http://localhost:9876/base/karma-shim.js:48564:35)
at Zone.runTask (http://localhost:9876/base/karma-shim.js:48453:47)
at drainMicroTaskQueue (http://localhost:9876/base/karma-shim.js:48700:35)
!-- the component
import { Component, OnInit } from '@angular/core';
import { TestService } from '../components/service/TestService';
@Component({
selector: 'my-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
providers: [TestService]
})
export class HomeComponent implements OnInit {
constructor(private testService: TestService) {
// Do stuff
}
ngOnInit() {
console.log('Hello Home', this.testService.getUsers());
}
}
!-- the service
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
@Injectable()
export class TestService {
constructor(public http: Http) {}
getUsers() {
return this.http.get('http://foo.bar');
}
}
!-- the test
import { inject, TestBed } from '@angular/core/testing';
import {BaseRequestOptions, Response, ResponseOptions, Http} from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import {TestService} from './TestService';
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
describe('Http', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
TestService,
BaseRequestOptions,
MockBackend,
{
provide: Http,
useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions],
},
],
});
});
beforeEach(inject([MockBackend], (backend: MockBackend) => {
const baseResponse = new Response(new ResponseOptions({ body: 'got response' }));
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
}));
it('should return response when subscribed to getUsers', inject([TestService], (testService: TestService) => {
testService.getUsers().subscribe((res: Response) => {
expect(res.text()).toBe('got response');
});
}));
});
I've fixed this problem doing the following:
move TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
to the beforeAll
function, so it look like this
describe('Http', () => {
beforeAll( ()=> {
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
});
beforeEach( () => {
TestBed.configureTestingModule({
providers : [...]
}
});
it('your tests...', inject([Provider], (provider:Provider)=>{});
You might also get this message Cannot set base providers because it has already been called(…)
Because you do have a setupFilesAfterEnv in your jest config file.
And one of those setupFiles
runs code which set base providers before you do.
Example:
jest.config.js
{
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
}
setup-jest.ts
# remove this line
`import 'jest-preset-angular/setup-jest';`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With