I am writing unit tests for a custom table module that uses several internal components. All the internal components use ForwardRef to access input to the main table, such as the columns. The component causing problems in the TestBed is the TableBody, which injects a config service that runs HTTP requests:
import { ConfigService } from '../services/config.service';
@Component({
selector: 'custom-table',
template: `...
<tbody [customTableBody]="dt.columns"...
`
})
export class Table {
_columns: any[];
@Input() get columns(): any[] {
return this._columns;
}
set columns(cols: any[]) {
this._columns = cols;
...
}
@Component({
selector: 'customTableBody',
template: `...`
})
export class TableBody implements OnInit {
_user: any;
@Input("customTableBody") columns: Column[];
constructor(@Inject(forwardRef(() => Table)) public dt: Table, private config?: ConfigService) { }
ngOnInit() {
this._user = this.config.getUser();
};
...
}
@NgModule({
exports: [Table],
declarations: [Table, TableBody,...]
})
export class TableModule { }
Test setup, setting up multiple custom tables to test different internal components, creating and providing a mock config service:
@Component({
template: `
<custom-table class="basicTable"...
<custom-table class="specialTable"...`
})
class TestTableComponent {...}
describe("CustomTable", () => {
let fakeConfigService: jasmine.SpyObj<ConfigService>;
beforeEach(() => {
fakeConfigService = jasmine.createSpyObj<ConfigService>('ConfigService', ['getUser']);
fakeConfigService.getUser.and.returnValue("TESTUSER");
TestBed.configureTestingModule({
imports: [
TableModule
],
providers: [
{ provider: ConfigService, useFactory: () => fakeConfigService }
],
declarations: [
TestBasicTableComponent, TableBody
]
});
...}
But even when I declare the provider for the fake service, import TableModule, and declare TableBody, it still doesn't appear to actually provide the fake service to the inner component, but instead try to import the real thing and fail with NullInjectorError: R3InjectorError(DynamicTestModule)[ConfigService -> HttpClient -> HttpClient]: NullInjectorError: No provider for HttpClient!. Am I missing something that will let the provider work on the inner component?
Please add
HttpClientTestingModuleto the imports!