3
votes

I have an issue with cdr.detectChanges() in my test. I have an error happening when it's called and I don't have any information, I just get this error :

ZoneAwareError@webpack:///~/zone.js/dist/zone.js:923:0 <- config/karma-shim.js:108645:28 invokeTask@webpack:///~/zone.js/dist/zone.js:398:0 <- config/karma-shim.js:108120:36 onInvokeTask@webpack:///~/zone.js/dist/proxy.js:103:0 <- config/karma-shim.js:107642:49

Is there a way to make detectChanges work?

I also tried something else by trying to make detectChanges do nothing by defining cdr in my test component configuration like this :

cdr = {
  detectChanges: () => {}
}

and then in the providers { provide: ChangeDetectorRef, useValue: cdr }, but when I console.info the cdr in the method tested it seems I still have the original cdr class.

I also tried with a fake class defined like this :

class FakeCDR {
  detectChanges(): void {

  }
}

and then { provide: ChangeDetectorRef, useClass: FakeCDR } in the providers, but same here.

Here's my test code:

it('should create an user', fakeAsync(inject([MockBackend],
  (backend: MockBackend) => {
    fixture.detectChanges()
    tick()

    component.newUser = User.newUserDraft()
    component.newUser.email = "[email protected]"
    component.createUser()
    tick()

    expect(component.newUser.email).toBe(User.newUserDraft().email)
  })))

and in createUser it's doing a service.createUser then do some stuff then cdr.detectChanges(). I did put console.info at every lines so I'm sure it's at the detectChanges that it fails.

1
show your test code, Change Detector is not provided through DI, it's a different mechanism, read hereMax Koretskyi
Added the test code, but it probably won't help youGuigui
@Guigui, Have you got any solution for this?Hary
@MaxKoretskyi, Is is not injected through DI?Hary

1 Answers

1
votes

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:

const changeDetectorRef = fixture.debugElement.injector.get(ChangeDetectorRef);
const detectChangesSpy = spyOn(changeDetectorRef.constructor.prototype, 'detectChanges');