Ad

Vue.js - Data Lost In Karma/phantomjs Tests

- 1 answer

I'm writting some unit tests for a Vue app. Everything is workign good when I try to test the DOM content, but I can't access the data of my components. In fact there is no data if I console.log my component $data property, it prints an empty object, no initially defined data or any other data. Just nothing.

Here is some code

some vue component

<template>
   <form @submit.prevent="saveAccount">
      <label for="accountType">Tipo de cuenta</label>
        <select class="form-control" id="accountType" v-model="newAccount.type">
          <option v-for="type in accountTypes" v-bind:value="type.value">
            {{type.label}}
          </option>
        </select>
   </form>
</template>
<script>
export default {
  data () {
    return {
      accountTypes: [
        {value: '1', label: 'Activo'},
        {value: '2', label: 'Pasivo'},
        {value: '3', label: 'Patrimonio'},
        {value: '4', label: 'INTO'}
      ]
    }
  }
}
</script>

My tests

  beforeAll(() => {
    vm = new Vue({
      template: '<div><account></account></div>',
      components: { account }
    }).$mount()
  })

  afterAll(() => {
    vm.$destroy(true)
  })

  it('account type', () => {
    // this pass
    expect(vm.$el.querySelectorAll('#accountType option').length).toBe(4)
    const options = vm.$el.querySelectorAll('#accountType option')
    // here accountTypes is undefined
    const accountValues = vm.accountTypes.map(type => {
      return type.value
    })
    options.forEach(option => {
      expect(accountValues.indexOf(option.value)).not.toBe(-1)
    })
  })

Some code is omitted. So, why is that my component data is empty but at the same time, properly rendered in the DOM?

Ad

Answer

After some try and error I found the answer and it's pretty obvious now. The thing is, that I was searching for data in the wrong place. The vmobject that I defined like this

vm = new Vue({
  template: '<div><account></account></div>',
  components: { account }
}).$mount()

Is a Vue instance that only have a component and a template option, the data I was searching for was in the child of that instance. So, I have to use this way to access data

const accountInstance = vm.$children[0]

This works, because to test I defined a single child easy to identify. I also tried before using const accountInstance = new account() but that throws an error because vue components ar not constructors

Ad
source: stackoverflow.com
Ad