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

如何Mock ApolloMutation组件?NuxtApollo测试Wrapper为空报错排查

解决Nuxt Apollo + Vue Test Utils测试时找不到.callMe元素的问题

嘿,我之前踩过类似的坑,你的问题核心在于shallowMount的特性和ApolloMutation组件的处理逻辑上,让我帮你理清楚:

问题根源

当使用shallowMount渲染组件时,它只会渲染当前组件的最外层结构,不会深入渲染子组件(比如ApolloMutation)的内部内容。而你的.callMe按钮是放在ApolloMutation的作用域插槽里的,默认情况下shallowMount完全不会渲染这部分DOM,自然就找不到目标元素了。

只mock$apollo对象是不够的——你还需要让ApolloMutation组件把插槽里的内容暴露出来,供测试代码访问。

解决方案:Mock ApolloMutation组件

我们可以给localVue注册一个mock版本的ApolloMutation组件,让它直接渲染默认插槽的内容,同时传递插槽需要的mutate、loading等参数。

修改后的测试代码如下:

import { createLocalVue, shallowMount } from '@vue/test-utils'
import VueApollo from '@nuxtjs/apollo'
import Register from '../pages/register/index.vue'

describe('Register user', () => {
  let localVue

  beforeEach(() => {
    localVue = createLocalVue()
    localVue.use(VueApollo, {})

    // 关键步骤:Mock ApolloMutation 组件,渲染插槽内容
    localVue.component('ApolloMutation', {
      props: ['mutation', 'variables'],
      render(h) {
        // 传递插槽需要的方法和状态,用jest.fn()模拟mutate方法
        return this.$scopedSlots.default({
          mutate: jest.fn(),
          loading: false,
          error: null
        })
      }
    })
  })

  it('Should click the register button to register', () => {
    const wrapper = shallowMount(Register, {
      localVue
    });
    
    // 现在能正常找到.callMe按钮了
    const callMeButton = wrapper.find('.callMe')
    callMeButton.trigger('click')
    
    expect(2+2).toBe(4)
  });
});

进阶:测试mutate方法调用

如果你还想验证点击"CreateUser"按钮时mutate是否被正确触发,可以把mock的mutate方法提取出来,方便做断言:

it('Should trigger mutate when create user button is clicked', () => {
  const mockMutate = jest.fn()
  
  // 注册带自定义mutate的mock组件
  localVue.component('ApolloMutation', {
    props: ['mutation', 'variables'],
    render(h) {
      return this.$scopedSlots.default({
        mutate: mockMutate,
        loading: false,
        error: null
      })
    }
  })

  const wrapper = shallowMount(Register, { localVue })
  // 找到触发mutate的按钮(不带.callMe类的那个)
  wrapper.find('button:not(.callMe)').trigger('click')
  
  // 断言mutate方法被调用
  expect(mockMutate).toHaveBeenCalled()
})

这样调整后,你的测试应该就能正常找到DOM元素,同时也能验证核心业务逻辑了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:22:08