Renderer2, RendererFactory2 in tests fails - TypeError: Cannot read property 'createElement' of undefined

1.1k Views Asked by At

I have a preferences service in an angular 9 application that create a script tag it use 'createElement' From Renderer2. When I try to mock the Renderer2 the createElement is not recognized.

This my service.ts :

 @Injectable()
 export class MyServer {

   private renderer: Renderer2;
   constructor(
     //....
     rendererFactory: RendererFactory2) {
     this.renderer = rendererFactory.createRenderer(null, null);
   }

   public createScript() {
    if (isLoginPage) {
      const script = this.renderer.createElement('script');
      script.type = 'text/javascript';
      script.src = 'urlScript';
      this.renderer.appendChild(document.body, script);
    }
  }
}

This my service.spec.ts : describe('MyServer', () => {

  describe('creerScriptTag', () => {

    beforeEach(() => TestBed.configureTestingModule({
      declarations: [],
      imports: [],
      providers: [
        MyServer,
        ConfigurationService,
        { provide: ModelService, useClass: ModelMockService },
        Renderer2
      ]
    }
    ));

    it('isLogin True verify that the script was created',
     inject([ConfigurationService, MyServer],
      (configurationService: ConfigurationService,
       myServer: MyServer,
       renderer2: Renderer2) => {
        spyOn(configurationService, 'getConfig').and.returnValue('anyString');
        myServer.createScript();

        expect(renderer2.createElement).toHaveBeenCalledTimes(1);
      })
    );
});

When I run the test I got this error TypeError: Cannot read property 'createElement' of undefined

Any idea please,

1

There are 1 best solutions below

0
On

I resolved this by create a const that contain the element that I need them, and I spy the RendererFactory2 to return the const that I created :

// create the const
const render2 = {createElement: jasmine.createSpy('createElement'), appendChild: 
jasmine.createSpy('appendChild')};

//mock of RendererFactory2 return the const
beforeEach(() => {
  spyOn(TestBed.get(RendererFactory2), 'createRenderer').and.returnValue(render2);
}
);

// I use the render2 const as it's my Renderer2
expect(render2.appendChild).toHaveBeenCalled();