4

I would like to test my component with Jest and inside component, I imported @vue/apollo-composable library and when I run test I get the error:

ReferenceError: define is not defined

      2 |   // libraries
      3 |   import { defineComponent, ref, watch } from '@vue/composition-api'
    > 4 |   import { useLazyQuery, useResult } from '@vue/apollo-composable'
        | ^
      5 |   import gql from 'graphql-tag'

In the jest test I don't use apollo-composable and I don't plan to. Code:

import '@/plugins/composition-api'
import App from '@/components/App.vue'
import Vue from 'vue'
import { Wrapper, createLocalVue, mount } from '@vue/test-utils'

Vue.use(Vuetify)

describe('SelectMediaProcess.vue', () => {
  let wrapper: Wrapper<Vue>
  const localVue = createLocalVue()
  beforeEach(() => {
    wrapper = mount(SelectMediaProcess, { localVue })
  })

  it('render', () => {
    expect(wrapper.exists()).toBe(true)
  })
})

I read on the internet what I can use:

jest.mock('@vue/apollo-composable', () => {
   // mock implementation
})

But when I use this piece of code in my test. I get error: (useLazyQuery is a function from @vue/apollo-composable library)

TypeError: Cannot read property 'useLazyQuery' of undefined

      19 |
      20 |       // get default media process
    > 21 |       const { onResult, load: loadDefaultMP } = useLazyQuery<
         | ^
      22 |         getDefaultMediaProcess,
      23 |         getDefaultMediaProcessVariables
      24 |       >(

Does anyone know what can I do please?

EDIT

I added these lines to my jest.config.js. It helped others but not me.

transformIgnorePatterns: ['<rootDir>/node_modules/(?!@vue/apollo-composable).+\\.js$']

moduleNameMapper: { '@vue/apollo-composable': '@vue/apollo-composable/dist/index.js' }

Full jest.config.js:

module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  moduleFileExtensions: ['js', 'ts', 'json', 'vue'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    'vuetify/lib(.*)': '<rootDir>/node_modules/vuetify/es5$1',
    '@vue/apollo-composable': '@vue/apollo-composable/dist/index.js'
  },
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  transform: {
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$':
      'jest-transform-stub',
    '^.+\\.ts?$': 'ts-jest',
    '.*\\.(vue)$': 'vue-jest'
  },
  transformIgnorePatterns: [
    '<rootDir>/node_modules/(?!(vuetify)/)',
    '<rootDir>/node_modules/(?!@vue/apollo-composable).+\\.js$'
  ]
}

and I get these new errors:

FAIL  tests/unit/selectMediaProcess.spec.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    C:\Users\u112200\Documents\deposit-frontend\node_modules\@vue\apollo-composable\dist\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export { useQuery, } from './useQuery';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token 'export'

      2 |   // libraries
      3 |   import { defineComponent, ref, watch } from '@vue/composition-api'
    > 4 |   import { useLazyQuery, useResult } from '@vue/apollo-composable'
        | ^
      5 |   import gql from 'graphql-tag'
      6 |   // models
      7 |   import { allMediaProcesses } from '../models/__generated__/allMediaProcesses'

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
      at src/components/SelectMediaProcess.vue:4:1
      at Object.<anonymous> (src/components/SelectMediaProcess.vue:89:3)

Does anyone know what can I do next please?

3 Answers 3

4

You need to define the functions within the mock statement.

Currently, you've said that rather than using the real thing a mock should be used. The reason you're then getting undefined is because the mock is empty (you've not defined any functions in it).

So, the next thing to do is to specify how that mocked library should interact. You're importing two functions, so you'll need to define those functions inside the mock statement:

jest.mock('@vue/apollo-composable', () => {
  return {
    __esModule: true,
    useLazyQuery: jest.fn(() => 42), // Replace 42 with whatever result you'd expect
    useResult: jest.fn(() => 43), // Replace 43 with whatever result you'd expect
  }
})

There's some more detail about this in the jest documentation.

Sign up to request clarification or add additional context in comments.

1 Comment

This works fine as long as you have only one useQuery or one useMutation in your component or child components, if you have more, you'd to identify each query/mutatioon to return the appropriately data.
2

Do you have a .babelrc file in your project? If so, you will need to change it to a babel.config.js (don't ask me why, only worked for me this way).

Also, you will need to add the following line to your jest.config.js

transformIgnorePatterns: ['node_modules/(?!@vue/apollo-composable)/']

In your case, you are already using a jest.config.js file, but in case you were using the package.json to define your testing config, you would need to create the jest config file.

This issue on GitHub helped me a lot on solving this issue: https://github.com/facebook/jest/issues/9395

Comments

0

If you wanna mock using jest, you use the following approach

jest.mock("apollo-client", () => ({
  __esModule: true,
  useQuery: (query: any) => {
    //other mocks if needed
  },
  useLazyQuery: jest.fn().mockReturnValue([
    jest.fn(), 
    {
      data: {
        yourProperties: "Add Here",
      },
      loading: false,
    },
  ]),
}));

As you see, this approach even returns the mock function that is called in the code to be tested.

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.