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 ?

7
  • 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 ? Commented Apr 1, 2018 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. Commented Apr 1, 2018 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 Commented Apr 1, 2018 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 Commented Apr 1, 2018 at 13:57
  • yes, already debug, all lines are running correctly. Commented Apr 1, 2018 at 13:59

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

2

Probably this can help:

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

1 Comment

Nop, That thing I have already tried, have tried use of done as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.