如何在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>
测试代码验证
- 保留
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'); // 断言失败,符合预期
- 移除
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
相关产品推荐
相关产品推荐

