Angular 测试中的RenderFactory2失败

Angular 测试中的RenderFactory2失败,angular,jasmine,Angular,Jasmine,我在angular 5应用程序中有一个preferences服务,它从本地存储加载'light-theme'或'dark-theme',并相应地向主体添加一个类 import {Injectable, OnDestroy, Renderer2, RendererFactory2} from '@angular/core'; // ... @Injectable() @AutoUnsubscribe() export class UiPreferencesService implements O

我在angular 5应用程序中有一个preferences服务,它从本地存储加载
'light-theme'
'dark-theme'
,并相应地向主体添加一个类

import {Injectable, OnDestroy, Renderer2, RendererFactory2} from '@angular/core';
// ...

@Injectable()
@AutoUnsubscribe()
export class UiPreferencesService implements OnDestroy {

private renderer: Renderer2;

    constructor(rendererFactory: RendererFactory2) {
        this.renderer = rendererFactory.createRenderer(null, null);
        this.loadPrefs();
    }
  // moar code
    private emitTheme(theme) {
        this.currentThemeSubject.next(theme);
        this.renderer.addClass(document.body, theme);
        this.renderer.removeClass(document.body, this.notCurrentTheme());
    }
}
我不得不使用
renderFactory2
,因为我在服务中使用了渲染器。我遇到的问题是在我的测试中:

无法在null上调用addClass


如何让RenderFactory2在测试中工作。

创建一个实现RenderFactory2的模拟类。在您的service.spec.ts中实例化,在您的提供程序中,您需要模拟RenderFactory2,并将create renderer设置为接收匿名函数:

mockProvider(RendererFactory2, {
     createRenderer: () => renderer2
}),
renderer2应该具有您需要的功能:

let renderer2: Renderer2 = {
        addClass: jasmine.createSpy('addClass'),
        removeClass: jasmine.createSpy('removeClass'),
    } as unknown as Renderer2;
然后,在测试中使用Render2:

expect(renderer2.addClass).toHaveBeenCalledWith(document.body, 'your-class');
比如说:

describe('Some name', () => {
    let renderer2: Renderer2 = {
        addClass: jasmine.createSpy('addClass'),
        removeClass: jasmine.createSpy('removeClass'),
    } as unknown as Renderer2;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [],
            providers: [
                ...your providers...,
                mockProvider(RendererFactory2, {
                    createRenderer: () => renderer2
                }),
            ],
        }).compileComponents();
    }));

    describe('adding a class to body', () => {
        it('renderer addClass should be called', () => {
            //your code which triggers class adding
            expect(renderer2.addClass).toHaveBeenCalledWith(document.body, 'your-class');
        });