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

如何在Cypress中验证API未被调用(缓存功能测试)

Cypress 如何断言API未被调用(缓存场景)

问题背景

我在应用中实现了API数据缓存,当数据已存在时不会重新获取。正向测试可以正常通过:

cy.intercept('**/api/things').as('api');
cy.visit('/things')                       
cy.wait('@api')                         // 测试通过

但验证缓存生效(断言API未被调用)时,以下代码会失败:

// 数据已从首次请求缓存,尝试断言无API调用但失败
cy.visit('/things2')                       
cy.wait('@api')                     
  .should('not.have.been.called')   // 因“未发起调用”超时失败

需要修改断言方式,实现类似cy.get().should('not.exist')的负向断言效果。

解决方法

不能使用cy.wait('@api')做负向断言——cy.wait()会强制等待目标请求出现,超时则直接失败。正确的做法是直接对拦截别名进行断言,Cypress会在断言超时前持续检查请求是否被触发。

基础写法

cy.intercept('**/api/things').as('api');
cy.visit('/things2');
// 直接断言该请求未被调用,默认超时时间可覆盖大部分场景
cy.get('@api').should('not.have.been.called');

更严谨的写法(配合时间控制)

如果请求是延迟触发的(比如用setTimeout包裹),可以用cy.clock()和cy.tick()快进时间,确保有足够时间验证请求未发起:

cy.intercept('**/api/things').as('api');
cy.clock(); // 接管时间控制
cy.visit('/things2');
cy.tick(1000); // 快进1秒,覆盖可能的延迟触发时间
cy.get('@api').should('not.have.been.called');

最小复现示例

测试页面代码

<body>
  <script>
    setTimeout(() => 
      fetch('https://jsonplaceholder.typicode.com/todos/1')
    }, 300)
  </script>
</body>

测试代码验证

  1. 保留fetch时(测试应该失败):
cy.intercept('https://jsonplaceholder.typicode.com/todos/1').as('fetchTodo');
cy.clock();
cy.visit('页面URL');
cy.tick(500); // 超过setTimeout的300ms
cy.get('@fetchTodo').should('not.have.been.called'); // 断言失败,符合预期
  1. 移除fetch后(测试应该通过):
cy.intercept('https://jsonplaceholder.typicode.com/todos/1').as('fetchTodo');
cy.clock();
cy.visit('页面URL');
cy.tick(500);
cy.get('@fetchTodo').should('not.have.been.called'); // 断言通过,符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:20:29