6

I am writing unit test for html div having a *ngIf condition.

<div *ngIf="clientSearchResults$ | async  as searchResults" class = 'fgf'  #datalist id="mydata" >
  <app-client-list id="clientDataTable1" class="clientDataTable dataTable" [clients]='searchResults'></app-client-list>
</div>

This ngIf condition gets true, when I recieved the data from ngrx store. Below is the component code, which filled this data.

searchData(client: Client) {
      //// some conditions
      this._clientService.getClientList()
     .subscribe(data => {
      const filteredData = this.filterData(data, client);
      this.isDataFound = filteredData !== null && filteredData.length > 0;
      this.testbool = true;
      /// In this line, my div got the data and using async condition, we 
      /// fill the div element.
      this.store.dispatch(new SetClientSearchResultsAction(filteredData));

    });
}

Now, when writing the unit test case for this.

it('should search the data with valid client passed from UI', async(() => {
    let debugFixture: DebugElement = fixture.debugElement;
    let htmlElement: HTMLElement = debugFixture.nativeElement;
    let clientListGrid = htmlElement.getElementsByClassName('fgf');
    let testbool= htmlElement.getElementsByClassName('testbool');

    spyOn(component, 'searchData').and.callThrough();
    spyOn(component, 'filterData').and.returnValue(CLIENT_OBJECT);
    spyOn(clientService, 'getClientList').and.callThrough();

    console.log("=========before======="+ clientListGrid.length);

    component.searchData(validClient);
    component.clientSearchResults$ = store.select('searchResults');
    fixture.detectChanges();
    debugFixture = fixture.debugElement;
    htmlElement = debugFixture.nativeElement;
    clientListGrid = htmlElement.getElementsByClassName('fgf');

    console.log("=========after ======="+ clientListGrid.length);

    expect(component.searchData).toHaveBeenCalled();
  }));

Problem is, in console, before calling the function, I am getting the length as 0 and after calling the function also, I am getting the length as 0. It should be 1, When We have received the data from store. And It is just because of this *ngif condition, *ngIf="clientSearchResults$ | async as searchResults"

Data is getting load in DIV, but still, in unit test I am not able to test this thing ?

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Nimish goel
  • 2,561
  • 6
  • 27
  • 42
  • Have you tried to use ``query(By.css('.fgf'))`` or ``query(By.css('.testbool'))`` ? are you sure that ``clientListGrid`` or ``testbool`` have the right content ? – HDJEMAI Apr 01 '18 at 13:45
  • yes, I have test that thing, TestBool css is on another div, it was just for testing purpose with simple ngif ( no async), and it is working correctly. – Nimish goel Apr 01 '18 at 13:48
  • Try to debug your test using chrome, you can then add some details about the lines of code you think are not giving the results, or try to create a demo with [stackblitz](https://stackblitz.com/edit/angular-testing-grhfjo?file=app%2Fapp.component.spec.ts) – HDJEMAI Apr 01 '18 at 13:54
  • In the component file, every line is running correctly, In HTML file, from unit testing when I am trying to access that particular div, that is not having any data. `clientListGrid = htmlElement.getElementsByClassName('fgf'); console.log("=========after ======="+ clientListGrid.length);` this should give some correct data. length as 1 when data has been loaded – Nimish goel Apr 01 '18 at 13:57
  • yes, already debug, all lines are running correctly. – Nimish goel Apr 01 '18 at 13:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167992/discussion-between-nimish-goel-and-hdjemai). – Nimish goel Apr 01 '18 at 14:06

2 Answers2

5

I know I’m too late but somebody might read it in future so.

I had the same problem and it was because of bug in Angular testing that it doesn’t trigger change detection when passed new value to input if the components ChangeDetectionStrategy is OnPush

So what you need to do is override it in Testing module:

TestBed.configureTestingModule({
  ... your declarations and providers
})
.overrideComponent(ComponentYoureTesting, {
  set: { changeDetection: ChangeDetectionStrategy.Default }
})
.compileComponents();

And it should work

nikagar4
  • 830
  • 4
  • 11
  • 23
2

Probably this can help:

it('should search the data with valid client passed from UI', fakeAsync(() => {
  // ---
  tick();
  fixture.detectChanges();
  // --- 
  expect(component.searchData).toHaveBeenCalled();
}));
shohrukh
  • 2,989
  • 3
  • 23
  • 38