Search code examples
angularkarma-jasminesubscription

How to test a component with subscription


Unit test with Subscription in a component with Jasmine/Karma Im trying to test if metatags are well generated by ngOninit in my page :

ngOnInit(): void {
    this.pagesSub = this.pagesService.initPage().subscribe();
  }

This is my InitPage function :

initPage(): Observable<Page> {
    return this.pageDbService.data$.pipe(
      map((pages: Page[]) => {
        let currentPage: Page;
        if (pages.length > 0) {
          this.setPagesToStore(pages);
          if (this.router.url === '/') {
            currentPage = pages[0]
          } else {
            currentPage = pages.find(page => ('/' + page.pageId) === this.router.url)
          }
        } else {
          this.setPagesToStore(pagesSeed);
          if (this.router.url === '/') {
            currentPage = pagesSeed[0]
          } else {
            currentPage = pagesSeed.find(page => ('/' + page.pageId) === this.router.url)
          }
        }
        this.seoService.generatePageTags(currentPage);
        return currentPage;
      })
    )
  }

And this is the generatePageTags function :

generatePageTags(page: Page) {
    const pageTitle = `${page.pageTitle} - IZIprint`;
    this.titleService.setTitle(pageTitle);
    this.meta.updateTag({ name: 'robots', content: 'index,follow' });
    this.meta.updateTag({ name: 'description', content: page.description });
    this.meta.updateTag({ property: 'og:type', content: 'website' });
    this.meta.updateTag({ property: 'og:title', content: page.socialTitle });
    this.meta.updateTag({ property: 'og:description', content: page.description });
    this.meta.updateTag({ property: 'og:url', content: page.ogUrl });
    this.meta.updateTag({ property: 'og:image', content: page.socialImage.thumbUrl });
    this.meta.updateTag({ property: 'og:determiner', content: 'auto' });
    this.meta.updateTag({ property: 'og:locale', content: 'fr_FR' });
    this.meta.updateTag({ property: 'og:site_name', content: 'IZIprint' });
    this.meta.updateTag({ name: 'twitter:card', content: 'summary_large_image' });
    this.meta.updateTag({ name: 'twitter:title', content: page.socialTitle });
    this.meta.updateTag({ name: 'twitter:description', content: page.description });
    this.meta.updateTag({ name: 'twitter:image', content: page.socialImage.thumbUrl });
  }

If I test with this test :

  it(`should have a metatag property="og:site_name" with content='IZIprint'`, fakeAsync(() => {
    meta = TestBed.inject(Meta);
    component.ngOnInit();
    fixture.detectChanges();
    flush();
    expect(meta.getTag('property="og:site_name"').content).toBe('IZIprint');
  }));

Jasmine-Karma does not find the content of 'property="og:site_name"' in my page. I am new to testing. Where is my mistake please ?


Solution

  • If there is a proper mock for the pageDbService.data$. the code bellow should be enough:

    it(`should have a metatag property="og:site_name" with content='IZIprint'`, async () => {
      component.ngOnInit();
      await fixture.whenStable()
    
      meta = TestBed.inject(Meta);
      expect(meta.getTag('property="og:site_name"').content).toBe('IZIprint');
    });
    

    fixture.detectChanges(); triggers the ngOnInit lifecycle hook. No need to call it them both. detectChanges also triggers change detection and rendering. This test doesn't depend on either of those. ngOnInit would be enough.

    The issue is the pageDbService.data$ mock. I don't see the code for it, so I can not say if this mock setup correctly.