I'm trying to write Angular unit test cases for filtering the mat-autocomplete options by inserting input data, but I couldn't able to do code coverage for value changes input.
app.component.html:
<div class="container">
<form [formGroup]="form">
<mat-form-field>
<input
matInput
type="text"
formControlName="name"
[matAutocomplete]="auto1"
/>
<mat-autocomplete #auto1="matAutocomplete">
<mat-option *ngFor="let data of data | async" [value]="data.name">
{{ data.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
</div>
app.component.ts:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { map, Observable, startWith } from 'rxjs';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
});
export class AppComponent implements OnInit {
data = [{
"id": 1,
"name": "One"
},{
"id": 2,
"name": "Two"
},{
"id": 3,
"name": "Three"
}];
form: FormGroup = this.formBuilder.group({
name: [''],
});
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.filteredNames = this.form.controls['name'].valueChanges.pipe(
startWith(''),
map((value) => this.getFilterData(value))
);
}
getFilterData(value) {
const filterValue = value.toLowerCase();
return this.data.filter((val) => val.name.toLowerCase().includes(filterValue));
}
}
app.component.spec.ts:
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { AppComponent } from './app.component';
const mockData = [{
"id": 1,
"name": "One"
},{
"id": 2,
"name": "Two"
},{
"id": 1,
"name": "Three"
}];
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
const formBuilder: FormBuilder = new FormBuilder();
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
FormsModule,
ReactiveFormsModule,
MatAutocompleteModule,
MatFormFieldModule,
MatInputModule,
],
declarations: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: FormBuilder, useValue: formBuilder },
],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('getSysValuechanges.', () => {
const spyFilter = spyOn<any>(component, 'getFilterData');
component.form.controls.name.setValue('Rambo');
expect(spyFilter).toHaveBeenCalled();
});
});
Can anyone please help me to write test cases for valuechanges on mat-autocomplete input element.
I found it, forgot to create mock service & inject in to spec.
let serviceSpy: jasmine.SpyObj<AppService>;
serviceSpy.getData.and.returnValue(of(mockData as any));
and inject the mock service.
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [,,,,]
declarations: [AppComponent],
providers: [
{ provide: AppService, useValue: serviceSpy},
],
}).compileComponents();
});