1

TL;DR

Unit Test for component copied from Vuetify link are passing but my actual unit test for my component written in pug is not passing.

Details:

I am working on a project which is built using Vue, NUXT, Vuetify and pug as template language. I am configuring the project to write test cases with JEST test runner. The unit test is currently failing and I would need some steps to identify the problem.

I have read through following:

Following versions are in use:

  • nuxt: ^2.0.0
  • nuxtjs/vuetify: ^1.10.2
  • pug: ^2.0.4
  • pug-plain-loader: ^1.0.0
  • jest: ^24.1.0
  • vue-jest: ^4.0.0-0

Following is the relevant folder structure

  • <project root>/jest.config.js
  • <project root>/components/common/CustomCard.vue
  • <project root>/components/common/MessageDialog.vue
  • <project root>/tests/unit/components/common/TestMessageDialog.spec.js
  • <project root>/tests/unit/components/common/TestCustomCard.spec.js

Following is are seemingly relevant parts of the configurations:

jest.config.js

module.exports = {
  verbose: true,
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1',
    '^~/(.*)$': '<rootDir>/$1',
    '^vue$': 'vue/dist/vue.common.js'
  },
  moduleFileExtensions: ['js', 'vue', 'json'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.*\\.(vue)$': 'vue-jest'
  },
  'collectCoverage': false,
  'collectCoverageFrom': [
    '<rootDir>/components/**/*.vue',
    '<rootDir>/pages/**/*.vue'
  ],
  globals: {
    'vue-jest': {
      pug: {
        doctype: 'html'
      }
    }
  },
  preset: '@vue/cli-plugin-unit-jest/presets/no-babel'
}

TestMessageDialog.spec.js

import {
  mount,
  createLocalVue
} from '@vue/test-utils'
import Vuetify from 'vuetify'
import MessageDialog from '@/components/common/MessageDialog.vue'

describe('MessageDialog.vue', () => {
  const sampleData = {
    titleText: 'title text with unique id : 2020.03.12.00'
  }

  let wrappedMessageDialog

  beforeEach(() => {
    const vuetify = new Vuetify()
    const localVue = createLocalVue()

    wrappedMessageDialog = mount(
      MessageDialog,
      {
        localVue,
        vuetify,
        propsData: sampleData
      }
    )
  })

  it('renders correctly when passed props', () => {
    expect(
      wrappedMessageDialog
        .find({ name: 'v-card-title' })
        .text()
    ).toMatch(sampleData.titleText)
  })
})

MessageDialog.vue

<template lang="pug">
v-dialog(v-model="isVisible" width="600")
  v-card
    v-card-title {{ titleText }}
</template>


<script>

export default {
  props: {
    titleText: {
      default: '',
      type: String
    }
  }
}
</script>

I am getting following error

FAIL tests/unit/components/common/TestMessageDialog.spec.js
[vue-test-utils]: find did not return Component, cannot call text() on empty Wrapper

      31 |       wrappedMessageDialog
      32 |         .find({ name: 'v-card-title' })
    > 33 |         .text()
         |          ^
      34 |     ).toMatch(sampleData.titleText)
      35 |   })
      36 | })

      at throwError (node_modules/@vue/test-utils/dist/vue-test-utils.js:1709:9)
      at ErrorWrapper.text (node_modules/@vue/test-utils/dist/vue-test-utils.js:8767:3)
      at Object.it (tests/unit/components/common/TestMessageDialog.spec.js:33:10)

  console.error node_modules/vue/dist/vue.common.dev.js:630
    [Vue warn]: Unknown custom element: <v-dialog> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

    found in

    ---> <Anonymous>
           <Root>

Similar warnings for <v-dialog>, <v-card> & <v-card-title>

skyboyer
  • 22,209
  • 7
  • 57
  • 64
zur
  • 1,121
  • 1
  • 11
  • 21

1 Answers1

2

Looks like you will want to register the components in the MessageDialog component. E.g.

<script>
import Foo from './Foo.vue;
...
export default {
  components: { Foo }
  ...
}
...
</script>

More info: https://v2.vuejs.org/v2/guide/components-registration.html#Local-Registration

tony19
  • 125,647
  • 18
  • 229
  • 307
AlexMA
  • 9,842
  • 7
  • 42
  • 64
  • Which component is to be imported ? v-dialog? It's working in source i.e. I can see the dialog in browser in application without that import. I think vuetify components aren't required to be imported like that. – zur Mar 13 '20 at 14:11
  • I see, you're probably using globally registered components. I personally prefer the local registration method. However, you can keep using global registration - but you'll need to stub the components being used, because in component unit tests the vue component is isolated from the main vue app. This might help: https://stackoverflow.com/questions/52962489/what-are-stubbed-child-components-in-vue-test-utils – AlexMA Mar 13 '20 at 14:16
  • It's midnight and I will have to pick it up after a break. Thanks but initial try failed ... mount and shallowMount behaved similarly. But I will give it another try. – zur Mar 13 '20 at 18:22