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

Cypress拦截Angular本地JSON请求时出现404问题求解

问题根源及解决方法

问题根源

  1. 拦截时机滞后:组件的ngOnInit在挂载瞬间就会发起请求,要是你在mount组件之后才配置cy.intercept,拦截规则根本赶不上请求触发的时间。
  2. 测试环境未加载assets资源:Cypress组件测试默认不会自动加载项目的assets目录,所以真实请求会直接返回404。
  3. URL匹配规则不精准:只写**/libraries.json可能失效,因为测试环境中请求的是完整URL(比如http://localhost:xxxx/assets/libraries.json),通配符的匹配范围或位置不对,也可能没指定请求方法导致匹配失败。

正确拦截方法

方法1:提前配置拦截+精确匹配路径

必须在挂载组件前定义拦截规则,确保请求触发前拦截已经生效,同时明确请求方法和完整路径:

describe('目标组件测试', () => {
  it('应该成功拦截libraries.json请求', () => {
    // 先设置拦截,放在mount操作之前
    cy.intercept('GET', '/assets/libraries.json', {
      body: { /* 这里放你的模拟数据 */ }
    }).as('getLibrariesData');

    // 挂载组件,确保导入HttpClientModule
    mount(目标组件, {
      imports: [HttpClientModule]
    });

    // 验证拦截是否触发
    cy.wait('@getLibrariesData');
  });
});

方法2:用正则匹配动态URL

如果测试服务的端口是动态变化的,用正则匹配URL的固定部分更稳妥:

cy.intercept('GET', /assets\/libraries\.json$/, {
  body: { /* 你的模拟数据 */ }
}).as('getLibrariesData');

额外可选方案:用Angular官方测试工具模拟请求

如果不想依赖Cypress的拦截,也可以用Angular自带的HttpClientTestingModule来模拟请求,这也是官方推荐的组件测试方式:

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

describe('目标组件测试', () => {
  let httpMock: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      declarations: [目标组件]
    });
    httpMock = TestBed.inject(HttpTestingController);
  });

  afterEach(() => {
    httpMock.verify(); // 确保没有未处理的请求残留
  });

  it('应该正确获取模拟的库数据', () => {
    const mockData = { /* 模拟数据 */ };
    const fixture = TestBed.createComponent(目标组件);
    
    // 捕获请求并返回模拟数据
    const req = httpMock.expectOne('/assets/libraries.json');
    expect(req.request.method).toBe('GET');
    req.flush(mockData);

    fixture.detectChanges();
    // 这里可以添加组件行为的断言逻辑
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:42:35