Jest with Vue 3 - ReferenceError: define is not defined
Jest with Vue 3 - ReferenceError: define is not defined
我想用 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/',
'vuetify/lib(.*)': '<rootDir>/node_modules/vuetify/es5',
'@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)
有谁知道我接下来该做什么吗?
您需要在 mock 语句中定义函数。
目前,您说过应该使用模拟而不是使用真实的东西。然后你取消定义的原因是因为模拟是空的(你没有在其中定义任何函数)。
因此,接下来要做的是指定模拟库应如何交互。您正在导入两个函数,因此您需要在 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
};
})
中有更多关于此的详细信息
您的项目中是否有 .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
如果你想用笑话来模拟,你可以使用下面的方法
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,
},
]),
}));
如您所见,这种方法甚至 returns 在要测试的代码中调用的模拟函数。
我想用 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/',
'vuetify/lib(.*)': '<rootDir>/node_modules/vuetify/es5',
'@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)
有谁知道我接下来该做什么吗?
您需要在 mock 语句中定义函数。
目前,您说过应该使用模拟而不是使用真实的东西。然后你取消定义的原因是因为模拟是空的(你没有在其中定义任何函数)。
因此,接下来要做的是指定模拟库应如何交互。您正在导入两个函数,因此您需要在 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
};
})
中有更多关于此的详细信息
您的项目中是否有 .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
如果你想用笑话来模拟,你可以使用下面的方法
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,
},
]),
}));
如您所见,这种方法甚至 returns 在要测试的代码中调用的模拟函数。