Reputation: 2468
I have a working app(when run ng serve
all works fine)
however, when I run ng test
compiler complains about not recognizing directives/properties such as Can't bind to 'formControl' since it isn't a known property of 'input'.
When I add
TestBed.configureTestingModule({
declarations: [
AppComponent,
SomeComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
.. other dependencies
]
what is the smart way not to add all the imports that I have already added in the app.module
?
UPDATE: I am talking about unit testing a component.
Upvotes: 3
Views: 2892
Reputation: 31
I solved this error by importing the module, where the tested component is declared in. This allows the test file to have access to the dependencies provided by the module.
I still need to separately import testing modules, for example HttpClientTestingModule
and RouterTestingModule
, in addition to the component's module, since the module doesn't use these. But this still reduces the amount of copy-paste needed and seems like a good approach to import only the needed modules instead of declaring everything in a shared module.
My module:
@NgModule({
declarations: [
TestedComponent,
],
imports: [
CommonModule,
DirectivesModule,
FormsModule,
PipesModule,
],
})
export class TestedComponentModule { }
My test file:
describe('TestedComponent', () => {
let component: TestedComponent;
let fixture: ComponentFixture<TestedComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
TestedComponent,
],
imports: [
HttpClientTestingModule,
RouterTestingModule,
TestedComponentModule,
],
}).compileComponents();
fixture = TestBed.createComponent(TestedComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Upvotes: 0
Reputation: 122
Since the error is Can't bind to 'formControl' since it isn't a known property of 'input', you will have to import following module/s under TestBed configuration. FormsModule, ReactiveFormsModule, MatInputModule, MatFormFieldModule
Ex: I have additional modules imported in my case and below is the sample code.
describe('SomeComponent', () => {
let component: SomeComponent;
let fixture: ComponentFixture<SomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SomeComponent],
imports: [HttpClientModule, RouterTestingModule, MatCardModule, MatIconModule, FormsModule, ReactiveFormsModule,
MatInputModule, MatProgressSpinnerModule, MatButtonModule, MatFormFieldModule,
BrowserAnimationsModule],
providers: [SomeService]
})
.compileComponents();
}));
function setup() {
const fixture = TestBed.createComponent(SomeComponent);
const component = fixture.componentInstance;
const someService = fixture.debugElement.injector.get(SomeService);
return { fixture, component, someService };
return { fixture, component };
}
it('should create app component', () => {
const { component } = setup();
expect(component).toBeTruthy();
});
});
Upvotes: 0
Reputation: 6821
Your tests are Independent from your app.module. So you need to import all needed modules.
If you want, you can do a shared.module.ts
where you have all the modules for test:
const MODULE_DEPENDENCIES = [
TranslateModule,
HttpClientModule,
ReactiveFormsModule,
ScrollingModule,
MatFormFieldModule,
MatInputModule,
];
@NgModule({
imports: MODULE_DEPENDENCIES,
exports: [
...MODULE_DEPENDENCIES
],
})
export class SharedModule {
constructor() { }
}
}
Upvotes: 4
Reputation: 2085
you can create a SharedModule which holds all your directives etc
or just reuse the array of modules
basically
export const modules: any[] = [
BrowserModule, ReactiveFormsModule
];
@NgModule({
imports: modules,
declarations: [ AppComponent, HelloComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
and in your test
TestBed.configureTestingModule({
declarations: [
AppComponent,
SomeComponent
],
imports: modules
I don't know of another way.
But you can do the same with declarations and providersa and save some typing with that
Upvotes: 1