Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spy on ChangeDetectorRef.detectChanges

Tags:

angular

I'm trying to test that a component calls detectChanges on it's injected ChangeDetectorRef

I've stepped through the code and it's definitely called, but it appears I'm getting different values for the ChangeDetectorRef in the component and in the test. Here's the code. I've also tried the commented out spy, but it didn't work either.

it('should call ChangeDetectorRef.detectChanges from onFixedUpdate', () => {
    let changeDetectorService = fixture.debugElement.injector.get(ChangeDetectorRef, null);
    let spy = spyOn(changeDetectorService, 'detectChanges').and.callThrough();
    //let spy = spyOn(fixture.changeDetectorRef, 'detectChanges').and.callThrough();

    expect(spy).not.toHaveBeenCalled();

    fixture.componentInstance.onFixedUpdate(1);

    expect(spy).toHaveBeenCalled();
});
like image 362
majinnaibu Avatar asked Jun 03 '17 07:06

majinnaibu


1 Answers

First some considerations:

  1. ChangeDetectorRef is not provided through DI, so you cannot provide a double.
  2. fixture.changeDetectorRef is not the same as the component provided, so you cannot use this.
  3. fixture.debugElement.injector.get(ChangeDetectorRef) will create a new instance of the private class ViewRef (the public class ViewRef is just an alias for ViewRef$1), every time it is invoked, then the object provided to the component is another.

So my solution is:

// Get a reference to an instance of the private class
const changeDetectorRef = fixture.debugElement.injector.get(ChangeDetectorRef);
// spy on private class prototype
const detectChangesSpy = spyOn(changeDetectorRef.constructor.prototype, 'detectChanges');
like image 75
Alex Parloti Avatar answered Nov 15 '22 06:11

Alex Parloti