十二、Mock Server——用Cypress拦截接口,前端测试不卡壳

Mock Server------用Cypress拦截接口,前端测试不卡壳

做前端测试时,经常遇到"后端接口还没好,前端没法测"的尴尬。这时候,Mock Server就成了救星------它能模拟接口返回,让前端在没有后端的情况下也能正常测试。Cypress不仅能调用接口,还能直接拦截和修改接口返回,自带"Mock功能",这一章咱们就来解锁这个技能。

一、什么是Mock?为什么需要它?

简单说,Mock就是"模拟"------当后端接口还没开发好,或者想测试异常场景(比如接口返回500错误)时,用Mock Server返回预设的结果,让前端测试能继续进行。

比如测试"登录失败"场景,不需要真的输错密码,直接Mock接口返回"密码错误"即可;测试"列表为空",直接让接口返回空数组,不用手动删数据。

二、Cypress自带的Mock:cy.intercept()

Cypress从6.0版本开始,用cy.intercept()命令替代了旧的cy.route(),专门用来拦截HTTP请求。它能做到:

  • 监听指定接口的请求;
  • 模拟接口返回(成功/失败/异常);
  • 修改请求参数或返回数据。

1. 基础用法:拦截接口并返回预设数据

比如拦截"获取商品列表"接口,让它返回我们准备好的Mock数据:

javascript 复制代码
it('Mock商品列表接口', () => {
  // 步骤1:定义Mock数据
  const mockProducts = [
    { id: 1, name: '测试商品1', price: 99 },
    { id: 2, name: '测试商品2', price: 199 }
  ]

  // 步骤2:拦截接口,返回Mock数据
  cy.intercept(
    'GET', // 拦截GET请求
    '/api/products', // 要拦截的接口路径
    mockProducts // 预设的返回数据
  ).as('getProducts') // 给拦截器起个别名,方便后续等待

  // 步骤3:访问页面,触发接口请求
  cy.visit('/products')

  // 步骤4:等待拦截的接口完成
  cy.wait('@getProducts')

  // 步骤5:验证页面展示正确
  cy.get('[data-cy=product-item]').should('have.length', 2)
  cy.get('[data-cy=product-name]').first().should('contain', '测试商品1')
})

这样一来,即使后端的/api/products接口还没好,页面也能展示我们的Mock数据,测试能正常进行。

2. 模拟异常场景:返回错误状态码

测试接口报错时的前端表现(比如显示错误提示),可以让Mock返回500、404等状态码:

javascript 复制代码
it('接口返回500时显示错误提示', () => {
  // 拦截接口,返回500错误
  cy.intercept(
    'GET',
    '/api/products',
    {
      statusCode: 500, // 状态码
      body: { message: '服务器内部错误' } // 错误信息
    }
  ).as('getProducts')

  cy.visit('/products')
  cy.wait('@getProducts')

  // 验证前端显示错误提示
  cy.get('[data-cy=error-message]')
    .should('be.visible')
    .and('contain', '服务器内部错误')
})

3. 动态修改返回数据:部分Mock

有时候不需要完全替换接口返回,只想改部分字段(比如把价格改成0测试折扣场景),可以先让请求走到真实接口,再修改返回数据:

javascript 复制代码
it('修改接口返回的价格字段', () => {
  // 先拦截,让请求正常发送到真实接口
  cy.intercept('GET', '/api/products', (req) => {
    // 等待真实接口返回后,修改数据
    req.continue((res) => {
      // 把所有商品价格改成0
      res.body.forEach(product => {
        product.price = 0
      })
    })
  }).as('getProducts')

  cy.visit('/products')
  cy.wait('@getProducts')

  // 验证价格都变成0
  cy.get('[data-cy=product-price]').each(($el) => {
    cy.wrap($el).should('contain', '0')
  })
})

三、自定义Mock Server:更灵活的场景

如果需要长期维护一套Mock数据,或者多人共享,可以用json-server搭建独立的Mock Server,配合Cypress使用:

1. 搭建本地Mock Server

  1. 安装json-server

    bash 复制代码
    npm install -g json-server
  2. 创建db.json文件,定义Mock数据:

    json 复制代码
    {
      "users": [
        { "id": 1, "name": "jane", "age": 20 },
        { "id": 2, "name": "kevin", "age": 25 }
      ],
      "products": [
        { "id": 1, "name": "手机", "price": 3000 }
      ]
    }
  3. 启动Mock Server:

    bash 复制代码
    json-server --watch db.json --port 3000

    访问http://localhost:3000/users,就能看到上面定义的用户数据了。

2. 在Cypress中调用Mock Server

测试时直接请求本地Mock Server的接口,不用依赖后端:

javascript 复制代码
it('调用自定义Mock Server的接口', () => {
  // 访问Mock Server的用户列表接口
  cy.request('GET', 'http://localhost:3000/users')
    .then((response) => {
      expect(response.status).to.equal(200)
      expect(response.body.length).to.equal(2)
      expect(response.body[0].name).to.equal('jane')
    })

  // 也可以结合UI测试
  cy.visit('/user-list') // 页面里的接口地址指向http://localhost:3000/users
  cy.get('[data-cy=user-item]').should('have.length', 2)
})

四、Mock的最佳实践

  1. 区分环境 :开发环境用Mock,测试环境用真实接口,在cypress.json里通过环境变量控制:

    json 复制代码
    {
      "env": {
        "useMock": true, // true用Mock,false用真实接口
        "mockBaseUrl": "http://localhost:3000"
      }
    }
  2. Mock数据贴近真实:尽量让Mock数据的格式、字段和真实接口一致,避免后期切换时出现兼容问题。

  3. 清理Mock状态 :用cy.intercept()时,在afterEach里重置拦截器,避免影响其他用例:

    javascript 复制代码
    afterEach(() => {
      cy.intercept('GET', '/api/products', (req) => {
        req.continue() // 让请求走真实接口
      })
    })
相关推荐
0思必得01 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5162 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino2 小时前
图片、文件的预览
前端·javascript
layman05284 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔4 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李4 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN4 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒4 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库4 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
电商API_180079052474 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫