trying to learn this testing utility TestBed
in angular-2 with a simple example and have hit my first blocker. google or SO search didn't yield any matching example,
so, I have a very basic component header
as below -
import { Component } from '@angular/core';
@Component({
selector: 'header',
template: ''
})
export class HeaderComponent{
public title: string;
constructor(testparam: string){
this.title = 'test';
}
}
and then have its spec as below -
import { TestBed } from '@angular/core/testing';
import { HeaderComponent } from './header.component';
describe('HeaderComponent Test', () => {
let component: HeaderComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [HeaderComponent]
});
const fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
});
it('should have the component defined', () => {
expect(component).toBeDefined();
});
it('should initialize the title to test', () => {
expect(component.title).toBe('test');
});
});
running the karma test is throwing -
Error: No provider for String! in karma.entry.js
karma.entry.js is basically just setting the test env configuration for TestBed and then goes thru each test in my spec folder, below is my karma.entry.js
require('core-js/es6');
require('core-js/es7/reflect');
require('es6-shim');
require('reflect-metadata');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('rxjs/Rx');
const browserTesting = require('@angular/platform-browser-dynamic/testing');
const coreTesting = require('@angular/core/testing');
coreTesting.TestBed.initTestEnvironment(
browserTesting.BrowserDynamicTestingModule,
browserTesting.platformBrowserDynamicTesting()
);
const context = require.context('../src', true, /\.spec\.ts$/);
context.keys().forEach(context);
Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000;
If I remove the parameter from the constructor of the component class, the tests pass, so I am thinking that I am missing some pre-configuration thats causing the TestBed.createComponent(HeaderComponent)
not to properly compile the component's constructor with the string type parameter.
any clue what I might be missing?
UPDATE:
if it helps anyone - based on @mrkosima's answer, my updated component class now looks like below and the unit tests all pass good now :)
import { Component, OpaqueToken, Inject } from '@angular/core';
export let TITLE_TOKEN = new OpaqueToken('title token');
@Component({
selector: 'header',
template: '',
providers: [{ provide: TITLE_TOKEN, useValue: 'test' }]
})
export class HeaderComponent{
public title: string;
constructor(@Inject(TITLE_TOKEN) titleParam: string){
this.title = titleParam;
}
}
OpaqueToken
wrapper. Earlier when I read DI, I skipped this portion just out of laziness :) and this was the issue. Thnx @mrkosima, I think this DI pattern makes sense because now with Typescript we would mostly be using OOPS patterns and would mostly be passing class-types or angular services to component constructors , thanks again. – Siward