Search code examples
vue.jsjestjsvue-test-utils

Vue Test Utils - Data persists between tests


I try to figure out how to start every test with fresh data, but I can't seem to make it work.

That's one of my test files:

import { createLocalVue, shallowMount } from '@vue/test-utils'
import Vue from 'vue'
import Vuetify from 'vuetify'
import VueFormGenerator from 'vue-form-generator'
import CustomerDetailsTabGroups from '@/modules/customer/view/component/CustomerDetailsTabGroups.vue'
import { customerMock } from './mocks/customerMock'

Vue.use(Vuetify)
Vue.use(VueFormGenerator)

const localVue = createLocalVue()

function createConfig (overrides) {
  let vuetify = new Vuetify()
  const config = {
    localVue,
    vuetify,
    mocks: {
      $translate: (msg) => msg
    },
    data: () => {
      return {
        schema: {},
        customerData: customerMock,
        groups: [
          {
            id: '111',
            name: 'Gruppe1',
            mainGroup: false
          },
          {
            id: '222',
            name: 'Gruppe2',
            mainGroup: false
          }
        ]
      }
    },
    propsData: {
      customer: customerMock,
      tabIndex: 1
    },
    sync: false
  }
  return overrides ? Object.assign(config, overrides) : config
}

describe('CustomerDetailsTabGroups.vue', () => {
  let wrapper

  beforeEach(() => {
    wrapper = shallowMount(CustomerDetailsTabGroups, createConfig(null))
  })

  afterEach(() => {
    wrapper.destroy()
    wrapper = null
  })

  test('renders correctly', () => {
    expect(wrapper.element).toMatchSnapshot()
  })

  test('watcher assign customer to customerData', async () => {
    wrapper = shallowMount(CustomerDetailsTabGroups, createConfig({
      propsData: {
        customer: { id: 'test' },
        tabIndex: 1
      }
    }))
    await wrapper.vm.$nextTick()
    expect(wrapper.vm.$data.customerData.id).toEqual('test')
  })

  test('addGroupToCustomer adds group to customer.customerGroups, sets mainGroup if no other mainGroup present and ' +
    'removes group from groups', () => {
    wrapper.vm.$data.customerData.customerGroups[0].mainGroup = false
    const castedWrapper = wrapper.vm as any
    castedWrapper.addGroupToCustomer(wrapper.vm.$data.groups[0])
    expect(wrapper.vm.$data.customerData.customerGroups.length).toEqual(2)
    expect(wrapper.vm.$data.customerData.customerGroups[1].mainGroup).toBeTruthy()
    expect(wrapper.vm.$data.groups.length).toEqual(1)
  })

  test('removeGroupFromCustomer removes group from customer.customerGroups, sets first customerGroup.mainGroup ' +
    'true if no other mainGroup present and adds group to groups', async () => {
    await localVue.nextTick()
    const castedWrapper = wrapper.vm as any
    castedWrapper.addGroupToCustomer(wrapper.vm.$data.groups[0])
    expect(wrapper.vm.$data.groups.length).toEqual(1)
    expect(wrapper.vm.$data.customerData.customerGroups.length).toEqual(2)
    castedWrapper.removeGroupFromCustomer(wrapper.vm.$data.customerData.customerGroups[0])
    expect(wrapper.vm.$data.customerData.customerGroups.length).toEqual(1)
    expect(wrapper.vm.$data.customerData.customerGroups[0].mainGroup).toBeTruthy()
    expect(wrapper.vm.$data.groups.length).toEqual(2)
  })
})

And that's the component I try to test:

import Vue from 'vue'
import customerMixin from '@/modules/customer/mixins/customerMixin'
import { Customer, CustomerGroup } from '@/modules/customer/type/types'
import {
  QUERY_CUSTOMER_GROUPS,
  QUERY_CUSTOMER_GROUPS_BY_ID
} from '@/modules/customer/graphql/queries'
import OverflowTooltip from '@/components/OverflowTooltip.vue'
import Event from '@/enum/event'

export default Vue.extend({
  name: 'CustomerDetailsTabData',
  mixins: [customerMixin],
  components: {
    OverflowTooltip
  },
  props: {
    customer: {
      type: Object,
      required: true
    },
    tabIndex: {
      type: Number,
      required: true
    }
  },

  data: function () {
    return {
      customerData: { customerGroups: [] } as Customer,
      groups: {}
    }
  },

  watch: {
    customer: {
      immediate: true,
      handler (customer: Customer): void {
        this.customerData = customer
        if (!this.customerData.customerGroups) {
          this.customerData.customerGroups = []
        }
      }
    }
  },

  methods: {
    addGroupToCustomer (groupToAdd: CustomerGroup): void {
      const customerMainGroup = this.customerData.customerGroups.find(group => group.mainGroup)
      groupToAdd.mainGroup = this.customerData.customerGroups.length === 0 || !customerMainGroup
      this.$set(this.customerData.customerGroups, this.customerData.customerGroups.length, groupToAdd)
      this.groups = this.groups.filter(group => group.id !== groupToAdd.id)
    },

    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.$set(this.groups, this.groups.length, groupToRemove)
      this.groups.sort((group1, group2) => group1.id - group2.id)
    },

    changeSelectedMainGroup (clickedGroup: CustomerGroup): void {
      this.customerData.customerGroups.forEach(group => {
        group.mainGroup = group.id === clickedGroup.id
      })
    }
  }
})

No matter what I try, test 4 failes cause it has groups from previous tests. Thought wrapper.destroy() and wrapper = null would erase the data between them, but doesn't work. Would appreciate any hints.


Solution

  • Gosh, for everyone facing the same problem, I found my problem. It was not that the wrapper hasn't been recreated everytime with fresh data. That worked. My problem was, that i directly bound my mocks to the tests and they changed the mock itself, so after every test the mock had different data. For me JSON.parse(JSON.stringify(mock))) the mocks did the trick.