You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

组件未注入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&shy;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&shy;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&shy;bla';
        const safeText: SafeHtml = sanitizer.bypassSecurityTrustHtml(text);
        component.safeHtml = safeText;
        expect(component.safeHtml).toBe(safeText);
    });
});

内容的提问来源于stack exchange,提问作者MojioMS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:20:32