组件未注入DomSanitizer时,如何在单元测试中使用它?
问题描述
我有一个未注入DomSanitizer的简单组件,代码如下:
export class ExampleComponent { @Input() public safeHtml: SafeHtml | undefined; }
我想在单元测试中使用DomSanitizer,尝试了提供并注入它,但测试代码运行报错。我的spec.ts文件如下:
describe('ExampleComponent', () => { let component: ExampleComponent; let fixture: ComponentFixture<ExampleComponent>; let sanitizer: DomSanitizer; await TestBed.configureTestingModule({ beforeEach(async() => { declarations: [ExampleComponent], providers: [DomSanitizer] // 组件未注入该服务 }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ExampleComponent); component = fixture.componentInstance; fixture.detectChanges(); sanitizr = TestBed.inject(DomSanitizer); // 我的尝试 }); it('should work with SafeHtml input', () => { expect(component).toBeTruthy(); let text = 'bla­bla'; let safeText: SafeHtml = sanitizer.bypassSecurityTrustHtml(text); // 此处报类型错误 component.safeHtml = safeText; expect(true); }); }
报错信息为:
TypeError: sanitizr.bypassSecurityTrustHtml is not a function
请问是否有办法在测试环境中使用真实的DomSanitizer,即便组件本身并未注入它?
解决方案
问题核心是你直接提供了DomSanitizer抽象类,而Angular的真实实现是DomSanitizerImpl,测试环境需要引入正确的实现才能正常调用方法。同时你的测试代码还有两处语法错误:await位置错误、变量名拼写错误(sanitizr应为sanitizer)。
以下是两种可行的解决方法:
方法一:导入BrowserTestingModule
BrowserTestingModule已经内置了DomSanitizer的完整实现,直接导入即可:
describe('ExampleComponent', () => { let component: ExampleComponent; let fixture: ComponentFixture<ExampleComponent>; let sanitizer: DomSanitizer; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ExampleComponent], imports: [BrowserTestingModule] // 引入测试模块 }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ExampleComponent); component = fixture.componentInstance; sanitizer = TestBed.inject(DomSanitizer); // 正确注入 fixture.detectChanges(); }); it('should work with SafeHtml input', () => { expect(component).toBeTruthy(); const text = 'bla­bla'; const safeText: SafeHtml = sanitizer.bypassSecurityTrustHtml(text); component.safeHtml = safeText; expect(component.safeHtml).toBe(safeText); // 替换无意义的断言 }); });
方法二:直接提供DomSanitizerImpl实现类
如果不想导入整个测试模块,可以直接提供具体实现类,并补充其依赖:
import { DomSanitizer, DomSanitizerImpl } from '@angular/platform-browser'; describe('ExampleComponent', () => { let component: ExampleComponent; let fixture: ComponentFixture<ExampleComponent>; let sanitizer: DomSanitizer; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ExampleComponent], providers: [ { provide: DomSanitizer, useClass: DomSanitizerImpl }, // 提供DomSanitizerImpl所需的依赖 { provide: 'SanitizationService', useValue: {} } ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ExampleComponent); component = fixture.componentInstance; sanitizer = TestBed.inject(DomSanitizer); fixture.detectChanges(); }); it('should work with SafeHtml input', () => { expect(component).toBeTruthy(); const text = 'bla­bla'; const safeText: SafeHtml = sanitizer.bypassSecurityTrustHtml(text); component.safeHtml = safeText; expect(component.safeHtml).toBe(safeText); }); });
内容的提问来源于stack exchange,提问作者MojioMS
相关产品推荐
相关产品推荐

