使组件测试具有主体或模拟 Renderer2 [英] Make the component test to have a body or mock Renderer2

查看:20
本文介绍了使组件测试具有主体或模拟 Renderer2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的一个组件中,我们使用 Renderer2 向 body 元素添加和删除一些 css 类/样式.为此,我们只需执行以下操作:

In one of our component, we use Renderer2 to add and remove some css classes/styles to the body element. To achieve that, we simply do something like:

this.renderer.setStyle(document.body, 'padding-left', '10px');
this.renderer.addClass(document.body, 'modal-container--opened');

一旦我们运行测试,就会遇到错误:

As soon as we run the tests, we encounter errors:

无法读取未定义的属性添加"

Cannot read property 'add' of undefined

无法设置未定义的属性'padding-left'

Cannot set property 'padding-left' of undefined

因此,角度 testBed 似乎没有创建任何 body 元素.

So it seems angular testBed doesn't create any body element.

在我们的测试配置中,如何创建一个 mocked body 元素?所以我们可以针对那个元素运行我们的测试,看看渲染器是否正确应用了样式/类.

似乎也无法模拟 Renderer2.

It also seems mocking the Renderer2 is not possible.

我们试图创建一个间谍:

We tried to create a spy:

let renderer: jasmine.SpyObj<Renderer2>;
renderer = jasmine.createSpyObj('renderer', ['addClass', 'removeClass', 'setStyle']);

然后在 TestBed.configureTestingModule 中(也在 overrideProviders 中进行了测试,但没有更多成功):

then in TestBed.configureTestingModule (also tested in overrideProviders without more success):

{ provide: Renderer2, useValue: renderer }

但是 Angular 完全忽略了这个覆盖.

But Angular ignores completely this override.

如何能够测试我们的组件行为,作用于 document.body?

推荐答案

与其模拟渲染器,不如尝试劫持它.这应该适用于 Angular 6+.

Instead of mocking the renderer try to hijack it. This should be working with Angular 6+.

在您的 component.spec.ts 中:

In your component.spec.ts:

let renderer2: Renderer2;
...
beforeEach(async( () => {
    TestBed.configureTestingModule({
        ...
        providers: [Renderer2]
    }).compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(YourComponent);
    // grab the renderer
    renderer2 = fixture.componentRef.injector.get<Renderer2>(Renderer2 as Type<Renderer2>);
    // and spy on it
    spyOn(renderer2, 'addClass').and.callThrough();
    // or replace
    // spyOn(renderer2, 'addClass').and.callFake(..);
    // etc
});

it('should call renderer', () => {
    expect(renderer2.addClass).toHaveBeenCalledWith(jasmine.any(Object), 'css-class');
});

这篇关于使组件测试具有主体或模拟 Renderer2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆