Search code examples
angularkarma-jasmineangular2-testingangular-unit-test

How to make the Angular 2 unit tests for Meta tags from the browser-platform library?


I am writing a unit tests for Angular 2 component with Jasmine. I will like to test if my document metatags as been set to a specific value when my component is instantiated. My component:

import { Component } from '@angular/core';
import { Meta } from '@angular/platform-browser';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {

  constructor (
    private meta: Meta
  ) {
    // Only 2 objects of metatag for example
    this.meta.addTags([
      {httpEquiv: 'X-UA-Compatible', content: 'IE=edge', title: '123'},
      {name: 'keywords', content: 'My keywords'}
    ], true)
  }  
}

Here what I have written for the testing but it is not working.

import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { Meta } from '@angular/platform-browser';
import { AppComponent } from './app.component';

describe('AppComponent', () => {

  let meta: Meta;
  let metatags: HTMLMetaElement[];
  let comp: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AppComponent ],
      providers: [ { provide: Meta } ],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    comp = fixture.componentInstance;
    fixture.detectChanges();
  });

  it(`should have a metatag name=keywords with content='My keywords'`, () => {
    meta = TestBed.get(Meta);
    expect(meta.getTag('name=keywords')).toBe('My keywords');
  });

  it(`should have a metatag httpEquiv=X-UA-Compatible with content: 'IE=edge' and title: '123'`, () => {
    metatags = TestBed.get(Meta);
    expect(metatags.getTags('httpEquiv=X-UA-Compatible').content).toBe('IE=edge');
    expect(metatags.getTags('httpEquiv=X-UA-Compatible').title).toBe('123');
  });
});

When I launch tests it give out some errors in console:


ERROR in src/app/app.component.spec.ts:27:47 - error TS2345: Argument of type '"My keywords"' is not assignable to parameter of type 'Expected'.

27   expect(meta.getTag('name=keywords')).toBe('My keywords');

src/app/app.component.spec.ts:32:21 - error TS2339: Property 'getTags' does not exist on type 'HTMLMetaElement[]'.

32   expect(metatags.getTags('httpEquiv=X-UA-Compatible').content).toBe('IE=edge');

src/app/app.component.spec.ts:33:21 - error TS2339: Property 'getTags' does not exist on type 'HTMLMetaElement[]'.

33   expect(metatags.getTags('httpEquiv=X-UA-Compatible').title).toBe('123');


Solution

  • I found a solution for this issue. Here is my new code:

    import { TestBed, async, ComponentFixture } from '@angular/core/testing';
    import { Meta } from '@angular/platform-browser';
    import { AppComponent } from './app.component';
    
    describe('AppComponent', () => {
    
      let meta: Meta;
      let metatags: HTMLMetaElement[];
      let comp: AppComponent;
      let fixture: ComponentFixture<AppComponent>;
    
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [ AppComponent ],
          providers: [
            { provide: Meta, useClass: Meta }
          ],
        }).compileComponents();
      }));
    
      beforeEach(() => {
        fixture = TestBed.createComponent(AppComponent);
        comp = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it(`should have a metatag name=keywords with content='My keywords'`, () => {
        meta = TestBed.get(Meta);
        expect(meta.getTag('name=keywords').content).toBe('My keywords');
      });
    
      it(`should have a metatag httpEquiv=X-UA-Compatible with content: 'IE=edge', title: '123'`, () => {
        metatags = TestBed.get(Meta).getTags('httpEquiv=X-UA-Compatible');
        metatags.forEach(el => {
          expect(el.content).toBe('IE=edge');
          expect(el.title).toBe('123');
        });    
      });
    });