angularangular-material2angular-material-6

Angular Material virtual scroll not rendering items in unit tests


I am using cdk-virtual-scroll-viewport + cdkVirtualFor in my component and it seems to work fine.

However in the unit test of that component the items don't get rendered.

I made a sample app based on this example and while the example works when you serve the app, the test I wrote fails.

app.module.ts

import { ScrollingModule } from '@angular/cdk/scrolling';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    ScrollingModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
  items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}

app.component.html

<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
  <div *cdkVirtualFor="let item of items" class="example-item">{{ item }}</div>
</cdk-virtual-scroll-viewport>

app.component.spec.ts

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ScrollingModule } from '@angular/cdk/scrolling';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports: [
        ScrollingModule,
      ],
    }).compileComponents();
  }));

  it('should render at least 4 items', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement as HTMLElement;
    expect(compiled.querySelectorAll('.example-item').length).toBeGreaterThanOrEqual(4); // <-- Error: Expected 0 to be greater than or equal 4.
  });
});

Solution

  • Changing the unit test (see in the question) to following resolved it:

    it('should render at least 4 items', fakeAsync(() => { // <---
      const fixture = TestBed.createComponent(AppComponent);
      fixture.autoDetectChanges(); // <--- 
      tick(500); // <---
      const compiled = fixture.debugElement.nativeElement as HTMLElement;
      expect(compiled.querySelectorAll('.example-item').length).toBeGreaterThanOrEqual(4);
    }));