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

如何在Apollo+Nuxt环境下测试Vue组件的async fetch()方法

问题原因&解法

你代码里存在3个核心错误:

  • 测试用例的test回调没有声明async,无法使用await处理异步逻辑
  • 测试时没有给组件注入mock的$apollo依赖,导致组件运行时访问this.$apollo报错
  • 测试作用域下的this不是组件实例,访问组件实例需要用wrapper.vm,且fetch方法需要手动触发并等待执行完成

方案1:仅测试variables构造逻辑(单元测试首选,无外部依赖)

直接mock Apollo客户端的query方法,捕获调用时传入的参数做校验,不需要真实发起GQL请求,测试速度最快。
修改后的测试代码如下:

// ProductList.spec.js
import { shallowMount } from '@vue/test-utils'
import ProductListing from '~/components/blocks/ProductListing.vue'
import PRODUCT_LISTING_BLOCK_QUERY from '~/queries/productListingBlock.gql'

import '@testing-library/jest-dom'

const directives = {
  interpolation: () => {}
}

// 预设模拟的返回数据
const mockProducts = [
  { id: 1, name: '测试商品1', sku: 'ms239' },
  { id: 2, name: '测试商品2', sku: 'mk332' }
]

// 存储Apollo query的调用参数,用于后续校验
let capturedQueryParams = null

const mocks = {
  $md: {
    render: value => value
  },
  // 新增mock $apollo依赖
  $apollo: {
    provider: {
      clients: {
        defaultClient: {
          query: (params) => {
            // 捕获调用参数
            capturedQueryParams = params
            // 返回模拟数据
            return Promise.resolve({
              data: { allProducts: mockProducts }
            })
          }
        }
      }
    }
  }
}

describe('ProductListing', () => {
  // 测试回调加async
  test('fetch方法构造variables正确', async () => {    
    const testVariables = {
      maxItems: 10,
      matchSkus: 'ms239,mk332,as484',
      matchTags: 'tag1,tag2,tag3',
      matchCategories: '111,222,333,444'
    }
    const wrapper = shallowMount(ProductListing, {
      propsData: testVariables,
      stubs: ['ProductTileList'],
      directives,
      mocks
    })

    // 手动调用fetch方法,等待执行完成
    await wrapper.vm.fetch()

    // 校验variables构造结果
    expect(capturedQueryParams.variables).toEqual({
      limit: 10,
      skus: ['ms239', 'mk332', 'as484'],
      tags: ['tag1', 'tag2', 'tag3'],
      categories: [111, 222, 333, 444]
    })
    // 校验query正确
    expect(capturedQueryParams.query).toBe(PRODUCT_LISTING_BLOCK_QUERY)
    // 校验context配置正确
    expect(capturedQueryParams.context.clientName).toBe('some-company')
    // 校验组件products赋值正确
    expect(wrapper.vm.products).toEqual(mockProducts)
  })
})

方案2:增加返回数据schema校验

如果需要校验返回数据结构符合预期,可以引入Zod等校验库定义schema,对返回的数据做格式校验:

  1. 先安装依赖:npm i zod -D
  2. 在测试文件中新增schema定义:
import { z } from 'zod'

// 定义返回商品的结构schema,可按实际业务字段调整
const ProductSchema = z.object({
  id: z.number(),
  name: z.string(),
  sku: z.string(),
  price: z.number()
})
const ProductsResponseSchema = z.array(ProductSchema)
  1. 在测试用例中新增校验逻辑:
// 校验返回数据格式符合schema
expect(() => ProductsResponseSchema.parse(wrapper.vm.products)).not.toThrow()

方案3:真实请求Apollo实例做集成测试

如果需要实际调用GQL接口测试完整链路,你需要在测试环境初始化你的Apollo客户端,然后把真实的客户端实例传入mock的$apollo配置中即可,注意需要提前处理测试环境的接口鉴权、跨域等问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:45:00