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

使用Mockito对Java API资源做单元测试时应测试哪些内容?

API 单元测试范围与 Mock 边界说明

核心原则:Mock 外部依赖,测试自身逻辑

你不需要模拟要测试的 API 路由层本身,只需要模拟它依赖的下层服务/外部调用:

  • 要 Mock 的内容:路由调用的 商品查询服务、用户校验模块 等下层依赖,所有和当前路由逻辑无关的外部返回都可以造假值
  • 要测试的内容:路由的入参校验逻辑、响应码映射规则、错误处理流程、返回体格式是否符合预期

针对 /shop/:itemId 接口的测试用例示例

我们以最常用的 Jest + Node.js 环境举例,其他语言框架逻辑完全通用:

前置准备

先 Mock 依赖的商品服务和用户校验服务,避免真实调用数据库/第三方服务:

jest.mock('./services/itemService', () => ({
  getItemById: jest.fn()
}))
jest.mock('./services/userService', () => ({
  checkUserEmailValid: jest.fn()
}))

const request = require('supertest')
const app = require('./app')
const { getItemById } = require('./services/itemService')
const { checkUserEmailValid } = require('./services/userService')

测试用例1:验证商品不存在的场景

test('请求不存在的商品ID返回ITEM_NOT_FOUND', async () => {
  // 模拟下层服务返回"商品不存在"的结果
  getItemById.mockResolvedValue(null)
  
  const res = await request(app).get('/shop/99999')
  
  // 校验返回结果是否符合预期
  expect(res.statusCode).toBe(404)
  expect(res.body.code).toBe('ITEM_NOT_FOUND')
})

测试用例2:验证用户邮箱非法场景

test('用户邮箱非法返回INVALID_EMAIL', async () => {
  // 模拟商品存在,但是用户邮箱校验不通过
  getItemById.mockResolvedValue({ id: 123, name: '测试商品', price: 99 })
  checkUserEmailValid.mockResolvedValue(false)
  
  const res = await request(app).get('/shop/123').set('user-email', 'invalid-email')
  
  expect(res.statusCode).toBe(403)
  expect(res.body.code).toBe('INVALID_EMAIL')
})

测试用例3:验证服务内部错误场景

test('下层服务抛出异常返回FAILURE', async () => {
  // 模拟商品服务抛出未知错误
  getItemById.mockRejectedValue(new Error('数据库连接超时'))
  
  const res = await request(app).get('/shop/123')
  
  expect(res.statusCode).toBe(500)
  expect(res.body.code).toBe('FAILURE')
})

测试用例4:验证正常请求成功场景

test('合法请求返回SUCCESS和商品信息', async () => {
  const mockItem = { id: 123, name: '测试商品', price: 99 }
  getItemById.mockResolvedValue(mockItem)
  checkUserEmailValid.mockResolvedValue(true)
  
  const res = await request(app).get('/shop/123').set('user-email', 'test@example.com')
  
  expect(res.statusCode).toBe(200)
  expect(res.body.code).toBe('SUCCESS')
  expect(res.body.data).toEqual(mockItem)
})

常见误区提醒

  • 不要 Mock 你要测试的目标路由的代码,Mock 的范围仅限它的 外部依赖
  • 所有响应码都要对应至少一条测试用例,确保每一个分支逻辑都被覆盖
  • 不需要测试下层服务的逻辑,比如商品服务本身的查询逻辑是否正确,那是商品服务单元测试要覆盖的内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:15:04