Jest Unit Test: wrapper.vm.$refs.editForm.validate is not a function

Total
3
Shares

When I write test case for form submit, i m getting issue with 1wrapper.vm.$refs.editForm.validate is not a function

I am unable to figure out the problem.. please Help me.

"@vue/cli-plugin-babel": "^3.11.0",
"@vue/cli-plugin-eslint": "^3.11.0",
"@vue/cli-plugin-pwa": "^3.11.0",
"@vue/cli-plugin-unit-jest": "^3.11.0",
"@vue/cli-service": "^3.11.0",
"@vue/eslint-config-prettier": "^5.0.0",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0"

==== EditProperty.vue======

<v-form ref="editForm" lazy-validation>
    <v-flex>
      <v-text-field label="Label Text" v-model="labelName" :rules="[v => !!v || 'Label Text is required']"

      />
    </v-flex>
</v-form>
<script>
export default {
  data() {
    return {
      labelName: ''
    }
  },
  methods: {
    save() {
      if (this.$refs.editForm.validate()) {
        this.$emit('updateLable', this.labelName)
      }
    }
  }
}
</script>

======EditProperty.spec.js =====

import { shallowMount, createLocalVue } from '@vue/test-utils'
import EditProperty from '@/components/EditProperty.vue'
import Vuetify from 'vuetify'
const localVue = createLocalVue()
localVue.use(Vuetify)
let wrapper
describe('EditProperty.vue', () => {
  beforeEach(() => {
    wrapper = shallowMount(EditProperty, {
      localVue,
      data() {
        return {
          labelName: 'Username'
        }
      }
    })
  })

  it('should save called correctly', () => {
    wrapper.vm.save()
  })
})

expected => test should be pass

getting => wrapper.vm.$refs.editForm.validate is not a function

When I write test case for form submit, i m getting issue with 1wrapper.vm.$refs.editForm.validate is not a function

I am unable to figure out the problem.. please Help me.


Solution

shallowMount does not render the child components. I.E. in your case, v-form won’t be rendered in the test. In fact if you call html from your wrapper, you will see a HTML comment in place of the <edit-form>.

The rationale behind that vue test utils feature is that, when you’re unit testing a component, you test only the logic of such component in isolation, and don’t rely on code from other modules.

Now you could manually pass an object as stub and provide any test double to allow the validate() call, via the stubs option:

import { shallowMount, createLocalVue } from '@vue/test-utils'
import EditProperty from '@/components/EditProperty.vue'
import Vuetify from 'vuetify'
const localVue = createLocalVue()
localVue.use(Vuetify)
let wrapper
describe('EditProperty.vue', () => {
  beforeEach(() => {
    const EditFormStub = {
      render: () => {},
      methods: {
        validate: () => true,
      }
    };
    wrapper = shallowMount(EditProperty, {
      localVue,
      stubs: {
        'edit-form': EditFormStub,
      }
      data() {
        return {
          labelName: 'Username'
        }
      }
    })
  })

  it('should save called correctly', () => {
    wrapper.vm.save()
  })
})

So we are passing a fake editForm as a stub, with a fake validate() method which always returns true.

Then you can test your component code. For instance, you could test that your label is emitted as updateLabel (in your original snippet it was ‘updateLable’, be wary):

    it('should save called correctly', () => {
      wrapper.vm.save();

      expect(wrapper.emitted('updateLabel')[0][0]).toBe(whatever the label should be)
    })
Leave a Reply

Your email address will not be published. Required fields are marked *