如何在Angular中模拟文档(HTMLDocument的阴影表示)?该实现在构造函数中使用了以下内容:
@Inject(DOCUMENT) private document: Document
在查看此How to inject Document in Angular 2 service之后,我在我的.spec设置中添加了以下内容:
const lazyPath = 'dummy';
const pathname = `/${lazyPath}`;
const document = { location: { pathname } as Location } as Document;
beforeEachProviders(() => ([ {provide: DOCUMENT, useValue: document} ]));
但它给了我错误:
ERROR in ./src/app/main/components/app-lazy/app-lazy.component.spec.ts
Module not found: Error: Can't resolve '@angular/core/testing/src/testing_internal' in '...'
resolve '@angular/core/testing/src/testing_internal' in '....'
Parsed request is a module
using description file: .../package.json (relative path: ...)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
当我在TestBed.configureTestingModule中使用简单的providers:[]而不是testing_internal包中的beforeEachProviders时,组件是未定义的,例如没有正确初始化。当我从一个注入文档切换到window对象(我不能在其中设置/mock位置)时,它只在单元测试中初始化(在非测试执行中都有效)。我能做什么?
发布于 2019-05-21 04:42:49
将此作为答案发布,因为格式在评论中不起作用。
如果可能的话,你能分享一个stackblitz吗?当我需要注入一个mock时,我通常会这样设置它:
// ... beginning of file
const mockDocument = { location: { pathname } };
beforeEach(() => TestBed.configureTestingModule({
imports: [...],
// Provide DOCUMENT Mock
providers: [
{ provide: DOCUMENT, useValue: mockDocument }
]
}));
// ...rest of file
发布于 2022-01-11 14:51:26
您应该避免模拟整个document对象,而应模拟/监视该对象上的单个方法/属性。
假设您的组件/服务中包含以下内容:
import { DOCUMENT } from '@angular/common';
...
constructor(@Inject(DOCUMENT) private document: Document) {}
您可以通过在beforeEach
中注入document对象来对其进行测试
describe('SomeComponent', () => {
let component: SomeComponent;
let doc: Document;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SomeComponent],
imports: [
RouterTestingModule,
HttpClientTestingModule
]
});
const fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
doc = TestBed.inject(DOCUMENT); // Inject here **************
});
it('set document title', () => {
component.setPageTitle('foobar'); // Assuming this component method is `this.document.title = title`
expect(doc.title).toBe('foobar');
});
it('calls querySelectorAll', () => {
const spy = spyOn(doc, 'querySelectorAll');
component.someMethodThatQueries();
expect(spy).toHaveBeenCalled();
});
});
https://stackoverflow.com/questions/56227820
复制相似问题