Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

help: TypeError: Cannot destructure property 'store' of '(0 , _compositionApi.useContext)(...)' as it is undefined. #716

Open
Edith2019 opened this issue Nov 14, 2022 · 0 comments
Assignees

Comments

@Edith2019
Copy link

Hi everyone,

I am setting up tests on a Nuxt2 app using @nuxtjs/composition-api and @vue/test-utils.

In addition, there is a vue-CLI UI library using @vue/composition-api and vue-demi.

The issue is that even if the context is mocked as per solution here, our store is still undefined and the tests are failling.

///// SET UP /////

The Nuxt2 app is set as follow:

Package.json

 "dependencies": {
   "@nuxtjs/composition-api": "^0.20.2",
   "core-js": "2",
 }

 "devDependencies": {
   "@vue/test-utils": "^1.3.0",
   "babel-core": "^7.0.0-bridge.0",
   "babel-jest": "^28.1.0",
   "jest": "^28.1.0",
   "jest-environment-jsdom": "^28.1.0",
   "jest-junit": "^14.0.0",
   "vue-jest": "^3.0.7",
 }

nuxt.config.js

 alias: {
    'vue-demi': '@nuxtjs/composition-api',
  },

jest.config.js

module.exports = {
  verbose: true,
  testEnvironment: 'jsdom',
  moduleFileExtensions: ['js', 'vue', 'json'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1',
    '^~/(.*)$': '<rootDir>/$1',
    '^vue$': 'vue/dist/vue.common.js',
    '^.+\\.(s?css|less)$': '<rootDir>/css_stub.js',
    '^@atoms/(.*)$':
      '<rootDir>/node_modules/UILIBRARY-path/$1',
    '^@molecules/(.*)$':
      '<rootDir>/node_modules/UILIBRARY-path/$1',
    '^@organisms/(.*)$':
      '<rootDir>/node_modules/UILIBRARY-path/$1',
  },
  transform: {
    '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
    '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
  },
  transformIgnorePatterns: ['<rootDir>/node_modules/UILIBRARY'],
  moduleDirectories: ['<rootDir>/node_modules/'],
  globals: {
    'vue-jest': {
      babelConfig: {
        configFile: './babel.config.js',
      },
    },
  },
  setupFilesAfterEnv: ['<rootDir>/test/unit/vueSetup.js'],
  collectCoverage: true,
  collectCoverageFrom: ['components/**.vue', 'pages/**.vue'],
  coverageDirectory: 'tmp/coverage',
  reporters: ['default', ['jest-junit', { outputDirectory: 'tmp/coverage' }]],
  coverageReporters: ['text', 'html', 'cobertura'],
  coverageThreshold: {
    global: {
      statements: 0,
      branches: 0,
      functions: 0,
      lines: 0,
    },
  },
}

test/vueSetup.js

import Vue from 'vue'
import Buefy from 'buefy'
import VueFormulate from 'UILIBRARY/vue-formulate/src/Formulate'
import { config } from '@vue/test-utils'

Vue.use(Buefy)
Vue.use(VueFormulate)

config.mocks.$t = (key) => key
config.mocks.$tc = (key) => key

///// Component and Test ////

Component.vue

export default {
    name: 'Component',
    setup() {
      const {
        store,
      } = useContext()
  
  // when consol.log(store), it is defined
  
      const gettingStoreData = computed(
        () =>
          store.getters['data']?.key === 1
      )
  }
}

test.spec.js

import { mount } from '@vue/test-utils'
import Component from '@/path-to-component/Component.vue'

jest.mock('@nuxtjs/composition-api')

describe('Component.vue', () => {
  const factory = (mockDataForm) => {
    const wrapper = mount(Component, {
      propsData: {
        various data
      },
      mocks: {
        $nuxt: {
          context: {
            store: {},
          },
        },

      },
      provide: {
        form: mockDataForm
      },
    })

    return wrapper
  }

  test('component mounts properly', () => {
    const wrapper = factory({
      various data
    })

    expect(wrapper.vm).toBeTruthy()
  })

There were a couple of attempts to define/ mock the store globally:

vueSetup.js

  • setting a mock store globaly
    config.mocks.store

  • adding $nuxt to Vue.prototype

Vue.prototype.$nuxt = {
 context: {
   store: {},
 },
}
  • creating a new Vue and adding store to its prototype
const newVue = new Vue({})

 newVue.prototype = (key) => key
  {
   context: {
     store: { $auth: {} 
},

But all of it result in the same error as in the title:

TypeError: Cannot destructure property 'store' of '(0 , _compositionApi.useContext)(...)' as it is undefined.

So what else could be done in order to not have an undefined store and be able to run the tests properly?

  • Should Vuex be added (which sounds not good as it is a nuxt app)
  • Is it actually only related to the store and not the context since mocking $t and $tc works fine?
  • Could it be linked to the component code itself and not the test?

Many thanks in advance for your support and please let me know if there is any missing information or if you need more details.

Cheers,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants