Reputation: 449
I am working through testing Angular code and seem to have some misunderstanding about template updates. What I am trying to get to work: I implemented a component which is a simply searchInput that can be cleared by a button click. [Template below] This works fine in practise, but I want to write a test for it.
<mat-form-field>
<mat-icon matPrefix>search</mat-icon>
<input #searchInput matInput (input)="onSearch(searchInput.value)"
[placeholder]="placeholder">
<button class="clear-search-button" mat-button *ngIf="searchInput.value" matSuffix mat-icon-button
(click)="searchInput.value=''; onSearch('')">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
My test currently looks like this [de = fixture.debugElement]:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NoopAnimationsModule, MatFormFieldModule, MatInputModule],
declarations: [SomeSearchComponent],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(SomeSearchComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
fixture.detectChanges();
});
it('should reset Input on button input', () => {
const input = de.query(By.css('input'));
expect(input).not.toBeNull();
input.value = 'someSearch';
fixture.detectChanges(); // Update view since now the input.value allows
the button to get added to DOM, since *ngIf-condition is now true.
const resetBtn = de.querySelector('button');
resetBtn.click();
fixture.detectChanges(); // Update view since now the input.value should be updated.
expect(input.value).toEqual('');
});
My problem is, that however I try to get the button, it does not seem to be added to the DOM, since I always get 'TypeError: Cannot read property 'click' of null' on the resetBtn.click()
line.
Is there a fundamental problem with my understanding of template testing or is there any silly typo?
Upvotes: 1
Views: 1089
Reputation: 3740
Your problem is that you probably think the function of input is getting triggered but it's not. While the dom isn't triggered this is problaby happening cause you just enterered the text but within a test the input event is not triggered you have to trigger it manual.
What you have to do is trigger it like:
input.value = 'someSearch';
input.dispatchEvent(new Event('input'));
My example:
let input = fixture.debugElement.query(By.css('input')).nativeElement;
input.value = '11';
input.dispatchEvent(new Event('input'));
Working example: https://stackblitz.com/edit/github-test-run-draft-1eta9b?file=src%2Fapp%2Fapp.component.spec.ts
Upvotes: 1