2

I tried to incorporate Angular Virtual inside one of my component and it works fine as intended on browser. However, when I try to write the test case for the same, the Karma runner throws the following set of error while initializing the component:

Error: Template parse errors:
Can't bind to 'cdkVirtualForOf' since it isn't a known property of 'ng-container'.
1. If 'cdkVirtualForOf' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component.
2. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("t">
      <cdk-virtual-scroll-viewport style="height: 150px" itemSize="90">
        <ng-container [ERROR ->]*cdkVirtualFor="let i of commentsData">
          <li class="commentBlock">
            <div>
"): ng:///DynamicTestModule/AppComponent3Component.html@11:22
Property binding cdkVirtualForOf not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("<ul class="list">
      <cdk-virtual-scroll-viewport style="height: 150px" itemSize="90">
        [ERROR ->]<ng-container *cdkVirtualFor="let i of commentsData">
          <li class="commentBlock">
         "): ng:///DynamicTestModule/AppComponent3Component.html@11:8
'cdk-virtual-scroll-viewport' is not a known element:
1. If 'cdk-virtual-scroll-viewport' is an Angular component, then verify that it is part of this module.
2. If 'cdk-virtual-scroll-viewport' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
    </h4>
    <ul class="list">
      [ERROR ->]<cdk-virtual-scroll-viewport style="height: 150px" itemSize="90">
        <ng-container *cdkVirtualF"): ng:///DynamicTestModule/AppComponent3Component.html@10:6

I tried to import the ScrollingModule to my .spec file and also the suggestions given by the Karma tool above, but it still fails.

My current spec file and app.module.ts file(where the component resides) looks as follows:

.spec file:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AppComponent3Component } from './app-component3.component';
import { SharedModule } from '@app/shared/shared.module';
import { Routes } from '@angular/router';
import { APP_BASE_HREF, CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { RouterTestingModule } from '@angular/router/testing';

describe('AppComponent3Component', () => {
  let component: AppComponent3Component;
  let fixture: ComponentFixture<AppComponent3Component>;

  beforeEach(async(() => {
    const routes: Routes = [
      {
        path: 'comp3',
        component: AppComponent3Component
      }
    ];

    TestBed.configureTestingModule({
      declarations: [AppComponent3Component],
      imports: [
        SharedModule.forRoot(),
        RouterTestingModule.withRoutes(routes),
        HttpClientModule,
        ScrollingModule,
        SharedModule.forRoot(),
        CommonModule
      ],
      providers: [{ provide: APP_BASE_HREF, useValue: '/' }]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent3Component);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('click button function works', async(() => {
    spyOn(component, 'continueFn');
    const button = fixture.debugElement.nativeElement.querySelector('button');
    button.click();

    fixture.whenStable().then(() => {
      expect(component.continueFn).toHaveBeenCalled();
    });
  }));
});

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { ScrollingModule } from '@angular/cdk/scrolling';

import { AppComponent1Component } from './app-component1/app-component1.component';
import { SharedModule } from '@app/shared/shared.module';
import { AppComponent3Component } from './app-component3/app-component3.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
     AppComponent1Component ,
    AppComponent3Component,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    SharedModule.forRoot(),
    HttpClientModule,
    ScrollingModule,
    ServiceWorkerModule.register('ngsw-worker.js', {
      enabled: environment.production
    })
  ],
  providers: [],
  bootstrap: [AppComponent1Component ]
})
export class AppModule {}
Laxminarayan
  • 76
  • 1
  • 6
  • I recommend trying to add `CUSTOM_ELEMENTS_SCHEMA` and if you still get errors, then add the `NO_ERRORS_SCHEMA`. Both of these are mentioned in the error messages. This should do it: `schemas: [ CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA ],`. Does adding those fix the problem? – JeffryHouser Jan 01 '19 at 17:36
  • @JeffryHouser, I did add them earlier to my app.module and they didnt seem to make any difference to the error – Laxminarayan Jan 01 '19 at 18:30
  • For clarity, my suggestion was to add the schemas to the `TestBed`, not the `app.module.ts` – JeffryHouser Jan 02 '19 at 04:45
  • I tried those as well without any luck – Laxminarayan Jan 02 '19 at 15:48

1 Answers1

3

For curious ones, this was fixed by importing ScrollingModule into all the injected services' spec files from other feature modules.

So, if your component is using service1 of featuremodule1, you need to update .spec file of service1 to import ScrollingModule.

Laxminarayan
  • 76
  • 1
  • 6
  • I'm glad you solved the issue, but If `service1` never uses `ScrollingModule`, there should be need to import it and doing so should not fix broken unit tests. Unfortunately, I don't understand enough of your structure to diagnose further. – JeffryHouser Jan 02 '19 at 04:47
  • That's something even i m confused about. But that fixed the issue suprisingly without breaking existing test cases – Laxminarayan Jan 02 '19 at 15:47