I have this root AppComponent
that listenens for a change on a service, and then adds or removes a CSS class on the document.body
import { Component, OnInit, Renderer2 } from '@angular/core';
import { SideMenuService } from './core/side-menu/side-menu.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
static readonly sideMenuClass: string = 'side-menu-open';
constructor(public sideMenuService: SideMenuService, private renderer2: Renderer2) { }
ngOnInit(): void {
this.sideMenuService.isOpenChange.subscribe((value: boolean) => {
if (value) {
this.renderer2.addClass(document.body, AppComponent.sideMenuClass);
} else {
this.renderer2.removeClass(document.body, AppComponent.sideMenuClass);
}
});
}
}
And then I have this in my *.spec.ts
file, much of which I took from reading this SO answer
import { TestBed, async, ComponentFixture, tick } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from './core/core.module';
import { AppComponent } from './app.component';
import { Renderer2, Type } from '@angular/core';
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let app: AppComponent;
let renderer2: Renderer2;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
CoreModule
],
declarations: [
AppComponent
],
providers: [Renderer2]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
app = fixture.debugElement.componentInstance;
//Spy on the renderer
renderer2 = fixture.componentRef.injector.get<Renderer2>(Renderer2 as Type<Renderer2>);
spyOn(renderer2, 'addClass').and.callThrough();
});
it(`should toggle a class on the <body> tag when opening/closing the side-menu via the side-menu service`, () => {
app.sideMenuService.open();
fixture.detectChanges();
console.log(fixture.debugElement.nativeElement, document.body)
expect(renderer2.addClass).toHaveBeenCalledWith(jasmine.any(Object), AppComponent.sideMenuClass);
});
});
However, right now it gives me the error message
Expected spy addClass to have been called with [ , 'side-menu-open' ] but it was never called.
What do I need to do to properly test this component? Am I even on the right track here?
Edit:
Here is the side-menu.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SideMenuService {
isOpen: boolean = false;
isOpenChange: Subject<boolean> = new Subject<boolean>();
constructor() {
this.isOpenChange.subscribe((value: boolean) => {
this.isOpen = value;
});
}
open(): void {
this.isOpenChange.next(true);
}
close(): void {
this.isOpenChange.next(false);
}
}