【问题标题】:Jest with Vue 3 - ReferenceError: define is not definedVue 3 的玩笑 - ReferenceError:未定义定义
【发布时间】:2021-07-17 16:26:43
【问题描述】:

我想用 Jest 和内部组件测试我的组件,我导入了 @vue/apollo-composable 库,当我运行测试时出现错误:

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'

在开玩笑的测试中,我不使用 apollo-composable,也不打算使用。代码:

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)
  })
})

我在网上看到了我可以使用的东西:

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

但是当我在测试中使用这段代码时。我收到错误:(useLazyQuery 是来自@vue/apollo-composable 库的函数)

TypeError: Cannot read property 'useLazyQuery' of undefined

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

有人知道我能做什么吗?

编辑

我将这些行添加到我的 jest.config.js 中。它帮助了其他人,但没有帮助我。

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

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

完整的 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$'
  ]
}

我得到了这些新错误:

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)

请问有谁知道我接下来可以做什么?

【问题讨论】:

    标签: vue.js jestjs importerror


    【解决方案1】:

    您需要在 mock 语句中定义函数。

    目前,您已经说过应该使用模拟而不是使用真实的东西。然后你得到 undefine 的原因是因为模拟是空的(你没有在其中定义任何函数)。

    因此,接下来要做的是指定模拟库应如何交互。您正在导入两个函数,因此您需要在 mock 语句中定义这些函数:

    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
      };
    }) 
    

    jest documentation 中有更多详细信息。

    【讨论】:

    • 只要您的组件或子组件中只有一个 useQuery 或一个 useMutation 就可以正常工作,如果您有更多,您需要识别每个查询/突变以返回适当的数据。
    【解决方案2】:

    您的项目中有.babelrc 文件吗?如果是这样,您需要将其更改为 babel.config.js(不要问我为什么,只对我有用)。

    另外,您需要将以下行添加到您的jest.config.js

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

    在您的情况下,您已经在使用 jest.config.js 文件,但如果您使用 package.json 来定义您的测试配置,则需要创建 jest 配置文件。

    GitHub 上的这个问题对我解决这个问题有很大帮助: https://github.com/facebook/jest/issues/9395

    【讨论】:

      【解决方案3】:

      如果你想用 jest 来模拟,你可以使用下面的方法

      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,
          },
        ]),
      }));
      

      如您所见,这种方法甚至返回要测试的代码中调用的模拟函数。

      【讨论】:

        猜你喜欢
        • 2022-07-12
        • 1970-01-01
        • 1970-01-01
        • 2022-10-16
        • 2021-09-17
        • 2021-09-06
        • 2020-05-29
        • 2021-09-12
        • 2020-12-04
        相关资源
        最近更新 更多