0

I'm brand new at Unit Testing with vue. I'm trying to unit test a navigation vue component. I started out easy, I just wanted to test a method that just makes a boolean false(triggered by an on click). I am also using vuetify. I somewhat managed to mimic a button and then my hope is that the variable I'm passing (showLoginDrawer) returns false in my unit test. My error is TypeError: _vm.is.has is not a function which relates to a different part of my code, I think I'm missing something but I couldn't find anything online about it.

Below I've included the component and my testing file.

//Nav.vue
<template>
  <v-btn
        :to="{ name: 'home' }"
        aria-label="Home button"
        @click="hideDiv()"
   >
   </v-btn>

      <div>
        <transition name="nav-fade">
          <component v-bind:is="drawerSection"></component>
        </transition>
      </div>

</template>
<script>
     data() {
      return {
        drawerSection: function () {
          if (this.is.has('learning')) {
            return 'nav-learning'
          } else {
            return 'nav-explore'
          }
        },
      }
    },
    methods: {
      hideDiv() {
        if (!this.appState.restrictedAccessAlert)
          this.appState.showLoginDrawer = false
      }
}
</script>
<style>//disregard</style>

//Nav.spec.js
import Vue from 'vue'
import Vuex from 'vuex'
import Vuetify from 'vuetify'
import { shallowMount, mount } from '@vue/test-utils'
import Nav from '@/components/Nav'


const localVue = createLocalVue()
localVue.use(Vuetify)
localVue.use(Vuex)

describe('Testing Nav component', () => {
    let vuetify
    beforeEach(() => {
      vuetify = new Vuetify()
    })
    test('Test Button click when logged out', () => {
    const wrapper = mount(Navigation, {
      data() {
        return {
          appState: {
            showLoginDrawer: true,
            lastCapabilityPath: '',
            restrictedAccessAlert: false,
          },
          is: 'learning',
          localVue,
          vuetify,
        }
      },
    })

    const event = jest.fn()
    const button = wrapper.findAll('.v-btn').at(0)
    expect(button.text()).toContain('My Profile')

    button.vm.$on('click', event)
    expect(event).toHaveBeenCalledTimes(0)
    expect(wrapper.vm.showLoginDrawer).toBeTruthy()
    button.trigger('click')
    expect(event).toHaveBeenCalledTimes(1)
    expect(wrapper.vm.showLoginDrawer).toBeFalsy()
  })
})

I get the error:

TypeError: _vm.is.has is not a function

Thank you for any help!

2
  • Because is property is not defined in the code you posted. This is what the error says. Commented Apr 1, 2022 at 21:43
  • when adding is I get TypeError: _vm.is.has is not a function. I didn't write this code and I can't find has anywhere so I assumed it was a built in of some sort. (Also sorry I forgot to add it int he code above, I was deleting some portion that was console log and stuff and I accidentally deleted that ) Commented Apr 1, 2022 at 21:48

2 Answers 2

1

Oh my mistake was that has() is a set function thus it won't work with a string so I had to make it equal to a set.

Updated code:

  test('Test Basic HTML rendering', () => {
    const is = new Set(['learning', 'b', 'c'])

    const wrapper = mount(Navigation, {
      data() {
        return {
          appState: {
            showLoginDrawer: true,
            lastCapabilityPath: '',
            restrictedAccessAlert: false,
          },
          is,
          localVue,
          vuetify,
        }
      },
    })
    wrapper.vm.$vuetify.breakpoint.smAndUp = true
    expect(wrapper.html()).toContain('Log-in')
    // check the name of the component
    expect(wrapper.vm.$options.name).toMatch('NavProfile')
  })
Sign up to request clarification or add additional context in comments.

2 Comments

Could you demonstrate with an inclusion of the code what was changed?
Yes! Just updated my response @Paul Williams
0

Please try use async & await, maybe every event call is asynchronous

describe('Testing Nav component', () => {
    let vuetify
    beforeEach(() => {
        vuetify = new Vuetify()
    })

    test('Test Button click when logged out', async () => { // use async
        const wrapper = mount(Navigation, {
            data() {
                return {
                    appState: {
                        showLoginDrawer: true,
                        lastCapabilityPath: '',
                        restrictedAccessAlert: false,
                    },
                    is: 'learning',
                    localVue,
                    vuetify,
                }
            },
        })

        const event = jest.fn()
        const button = wrapper.findAll('.v-btn').at(0)
        expect(button.text()).toContain('My Profile')

        button.vm.$on('click', event)
        expect(event).toHaveBeenCalledTimes(0)
        expect(wrapper.vm.showLoginDrawer).toBeTruthy()

        // Try use await at every event
        await button.trigger('click')
        expect(event).toHaveBeenCalledTimes(1)
        expect(wrapper.vm.showLoginDrawer).toBeFalsy()
    })
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.