进行组件测试以具有主体或模拟Renderer2 [英] Make the component test to have a body or mock 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:
无法读取未定义的属性"add"
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.
在我们的测试配置中,如何创建模拟的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
来测试我们的组件行为?
How to be able to test our component behavior, acting on 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屋!