Chund
Chund

Reputation: 449

Template Updates do not happen in test

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

Answers (1)

Swoox
Swoox

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

Related Questions