2

StaticInjectorError(DynamicTestModule)[MatTable -> ChangeDetectorRef]: StaticInjectorError(Platform: core)[MatTable -> ChangeDetectorRef]: NullInjectorError: No provider for ChangeDetectorRef!

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { MessagesComponent } from './messages.component';
import { NgModule,CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA} from '@angular/core';
import { MatTableModule } from '../../../MessageUtility/node_modules/@angular/material';
import { HttpClientModule } from '@angular/common/http';
import { RouterTestingModule  } from '@angular/router/testing';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MessagesComponent ],
    imports:[HttpClientModule,RouterTestingModule,MatTableModule, ],
      schemas: [NO_ERRORS_SCHEMA,NO_ERRORS_SCHEMA]
    })
    .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
Cœur
  • 37,241
  • 25
  • 195
  • 267
Gayatri G
  • 31
  • 1
  • 7

2 Answers2

4

Another approach is to provide all required methods of ChangeDetectorRef as part of your TestBed.configureTestingModule declaration.

For example if your code (or a 3rd library like in your case) uses the detectChanges method of the ChangeDetectorRef instance you can provide it as in the following example:

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                // other providers here
                { provide: ChangeDetectorRef, useValue: { detectChanges: () => { } } }
            ]
        });
    });

Nikos Tsokos
  • 3,226
  • 2
  • 34
  • 41
3

Are you using ChangeDetectionStrategy.OnPush as your Change Detection Strategy? ChangeDetectorRef is actually exposed to the fixture, as explained here.

If you have defined ChangeDetectorRef as one of your private attributes in your component like this:

constructor(private cdr: ChangeDetectorRef) { }

Since it is private, you should create a spy as a stub for that attribute in your test file, and test if the ChangeDetectorRef is being called. Simply mock the CDR on your .spec file by doing this:

it('test CDR', () => {
  const spyCDR = spyOn((component as any).cdr, 'detectChanges'); 

  component.method();    
  expect(spyCDR).toHaveBeenCalled();
});
wentjun
  • 40,384
  • 10
  • 95
  • 107