You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Vue Test Utils:测试间数据残留问题排查与解决求助

解决Vue测试用例间数据污染的问题

我帮你排查了下,你遇到的核心问题是测试用例之间的状态泄漏——根源在于你复用了同一个引用类型的customerMock对象,测试中对数据的修改会直接影响到后续测试的初始状态。另外还有几处小细节需要调整,下面一步步来解决:

1. 用工厂函数生成独立的Mock对象

customerMock是引用类型,当你在测试里修改customerData.customerGroups时,本质是在修改原mock对象的内容(对象是引用传递),后续测试拿到的自然是被改脏的数据。

解决方法:把customerMock改成工厂函数,每次调用都返回全新的对象副本:

// 替换原来的customerMock导出
export const customerMock = () => ({
  // 这里填入你原来的mock内容,比如:
  id: 'mock-customer-id',
  customerGroups: [
    { id: 'default-group', mainGroup: true }
    // 其他属性...
  ]
})

然后在createConfig和测试里调用这个函数获取新对象:

// createConfig里的data和propsData修改如下
data: () => {
  return {
    schema: {},
    customerData: customerMock(), // 调用函数生成新对象
    groups: [
      { id: '111', name: 'Gruppe1', mainGroup: false },
      { id: '222', name: 'Gruppe2', mainGroup: false }
    ].map(item => ({...item})) // 深拷贝每个group对象,确保完全独立
  }
},
propsData: {
  customer: customerMock(), // 同样生成新的mock对象
  tabIndex: 1
}

2. 修正组件中groups的初始化逻辑

看你的组件代码,data里的groups初始化为{},但后续你用了filtersort这些数组方法,这会直接报错。应该把它初始化为空数组:

data: function () {
  return {
    customerData: { customerGroups: [] } as Customer,
    groups: [] // 改成空数组,而非空对象
  }
}

3. 优化测试的wrapper创建方式

你在第二个测试里直接重新赋值了wrapper,这会破坏beforeEach/afterEach的清理逻辑。建议要么单独创建并销毁测试专属的wrapper,要么用setProps来修改props:

方式一:单独创建测试wrapper

test('watcher assign customer to customerData', async () => {
  const testCustomer = { id: 'test' }
  // 创建测试专属的wrapper
  const testWrapper = shallowMount(CustomerDetailsTabGroups, createConfig({
    propsData: { customer: testCustomer, tabIndex: 1 }
  }))
  await testWrapper.vm.$nextTick()
  expect(testWrapper.vm.$data.customerData.id).toEqual('test')
  testWrapper.destroy() // 手动销毁
})

方式二:用setProps修改现有wrapper的props

test('watcher assign customer to customerData', async () => {
  await wrapper.setProps({ customer: { id: 'test' } })
  await wrapper.vm.$nextTick()
  expect(wrapper.vm.$data.customerData.id).toEqual('test')
})

4. 修复组件方法中的数组操作问题

你的removeGroupFromCustomer方法里用this.$set往数组里加元素,这不是数组的正确用法,应该用push来保持响应性:

removeGroupFromCustomer (groupToRemove: CustomerGroup): void {
  this.customerData.customerGroups = this.customerData.customerGroups.filter(group => group.id !== groupToRemove.id)
  if (groupToRemove.mainGroup && this.customerData.customerGroups.length > 0) {
    this.changeSelectedMainGroup(this.customerData.customerGroups[0])
    groupToRemove.mainGroup = false
  }
  this.groups.push(groupToRemove) // 替换$set,用push添加元素
  this.groups.sort((group1, group2) => group1.id - group2.id)
}

最后验证

做完这些调整后,每个测试都会拿到完全独立的初始数据,不会再受前序测试的影响。核心思路就是避免共享引用类型的测试数据,确保每个测试都从干净的状态开始执行。

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

火山引擎 最新活动