You need to enable JavaScript to run this app. 如何测试向Angular DOCUMENT注入脚本的LoadService服务功能
优惠活动
大模型
产品
解决方案
定价
更多

如何测试向Angular DOCUMENT注入脚本的LoadService服务功能

问题根源

Jest搭配的JSDOM环境默认禁止加载外部资源,你注入的script标签不会实际发起网络请求,因此所有加载相关事件都不会触发,导致Promise一直处于pending状态最终超时。
单元测试场景下不建议依赖外部网络请求,我们只需要验证服务的行为逻辑即可,不需要真实加载远程脚本。

正确测试方案

我们通过手动触发script元素的加载事件来验证服务逻辑,不需要发起真实网络请求,修改后的测试代码如下:

/**
 * @jest-environment jsdom
 */

import { test, expect, beforeAll } from '@jest/globals';
import { TestBed } from '@angular/core/testing';
import { LoadService } from './load-scripts.service';
import { DOCUMENT } from '@angular/common';

let service: LoadService;
let doc: Document;

beforeAll(() => {
  TestBed.configureTestingModule({
    providers: [LoadService], // 修正原测试中provider写错的问题
  });
  service = TestBed.inject(LoadService);
  doc = TestBed.inject(DOCUMENT); // 拿到测试环境的document实例
});

test('service should be created', () => {
  expect(service).toBeTruthy();
});

test('the script should be loaded successfully', async () => {
  // 调用load方法
  const loadPromise = service.load('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js');
  
  // 找到刚插入到head的script元素
  const insertedScript = doc.head.querySelector('script[src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"]') as HTMLScriptElement;
  expect(insertedScript).toBeTruthy();
  expect(insertedScript.async).toBe(true); // 验证async属性正确设置

  // 手动触发load事件
  insertedScript.dispatchEvent(new Event('load'));

  // 验证Promise正常resolve
  await expect(loadPromise).resolves.not.toThrow();
});

test('the script load should throw error when failed', async () => {
  const loadPromise = service.load('invalid-url');
  const insertedScript = doc.head.querySelector('script[src="invalid-url"]') as HTMLScriptElement;
  
  // 手动触发error事件
  insertedScript.dispatchEvent(new Event('error'));

  // 验证Promise正常reject
  await expect(loadPromise).rejects.toBeDefined();
});
可选方案(不推荐,仅作参考)

如果你确实需要真实加载远程脚本,可以开启JSDOM的资源加载能力,只需要在测试文件顶部修改JSDOM配置:

/**
 * @jest-environment jsdom
 * @jest-environment-options {"resources": "usable"}
 */

该方案的缺点:

  • 依赖网络环境,网络波动会导致测试失败
  • 测试执行速度慢
  • 外部资源不可用时测试直接失败,不符合单元测试稳定性要求
服务优化建议

你当前的服务里监听了loaded、complete、readystatechange三类冗余事件,这些都是旧IE版本的兼容用事件,现代浏览器(IE11及以上)只需监听load和error两类事件就足够覆盖所有场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 14:48:01