typescript - 如何在开玩笑的单元测试中使用 vue3 + typescript 在 shallowMount() 中添加假商店?
问题描述
我迷路了,我阅读了能够store
在shallowMount()
功能中添加假的文档。
在官方文档中:https ://vue-test-utils.vuejs.org/guides/using-with-vuex.html ,所以我实现了这个示例
import { createLocalVue, shallowMount } from "@vue/test-utils";
import ProjectItem from "@/components/ProjectItem.vue";
import { state } from "@/data/fakeStore/projects";
import Vuex from "vuex";
describe("ProjectItem.vue", () => {
const localVue = createLocalVue();
localVue.use(Vuex);
const fakeStore = new Vuex.Store({
state: state,
getters: {
projects: jest.fn(),
skills: jest.fn(),
skillsFromOneProject: jest.fn()
}
});
const wrapper = shallowMount(ProjectItem, {
props: {
index: 0
},
fakeStore,
localVue
});
it("check initialization data", () => {
expect(wrapper.vm.projects).toEqual(state.projects);
expect(wrapper.vm.skills).toEqual(state.skills);
expect(wrapper.vm.index).toEqual(0);
});
});
但我不能使用createLocalVue
,因为我得到了
模块“@vue/test-utils”没有导出成员“createLocalVue”。
此外在线shallowMount(ProjectItem,
我收到以下错误
没有重载匹配此调用。最后一个重载给出了以下错误。'DefineComponent<{}, {}, any, ComputedOptions, MethodOptions, ComponentOptionsMixin, ComponentOptionsMixin, ... 4 more ..., {}>' 类型的参数不能分配给 'ComponentOptionsWithObjectProps<Readonly<ComponentPropsOptions> 类型的参数, {}, any, ComputedOptions, MethodOptions, ComponentOptionsMixin, ... 4 更多 ..., { ...; } | {}>'。类型 'DefineComponent<{}, {}, any, ComputedOptions, MethodOptions, ComponentOptionsMixin, ComponentOptionsMixin, ... 4 more ..., {}>' 不可分配给类型 'ComponentOptionsBase<Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; join?: string | undefined; ... 19 更多 ...; toLocaleString?: 字符串 | 不明确的; }) | ({ ...; } & ... 还有 1 个 ... & { ...; })>...'。属性“设置”的类型不兼容。类型 '((this: void, props: Readonly<LooseRequired<Readonly<{} & {} & {}>>>, ctx: SetupContext<{}>) => void | {} | RenderFunction | Promise<... >) | undefined' 不能分配给类型 '((this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; ... 20 more ...; toLocaleString?: string | undefined; }) | ({ ...; } & ... 1 more .. . & { ...; })> & ...'。类型'(this: void, props: Readonly<LooseRequired<Readonly<{} & {} & {}>> >, ctx: SetupContext<{}>) => 无效 | {} | 渲染函数 | Promise<...>' 不能分配给类型 '(this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; ... 20 more ...; toLocaleString?: string | undefined; }) | ({ ...; } & ...还有 1 个 ... & { ...; })> & {...'。参数类型 'ctx' 和 'ctx' 不兼容。类型 'SetupContext<string[]>' 不可分配给类型 'SetupContext <{}>'。类型“{}”缺少类型“string[]”的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25) : 最后一个重载在这里声明。设置上下文<{}>) => 无效 | {} | 渲染函数 | Promise<...>' 不能分配给类型 '(this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; ... 20 more ...; toLocaleString?: string | undefined; }) | ({ ...; } & ...还有 1 个 ... & { ...; })> & {...'。参数类型 'ctx' 和 'ctx' 不兼容。类型 'SetupContext<string[]>' 不可分配给类型 'SetupContext <{}>'。类型“{}”缺少类型“string[]”的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25) : 最后一个重载在这里声明。设置上下文<{}>) => 无效 | {} | 渲染函数 | Promise<...>' 不能分配给类型 '(this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; ... 20 more ...; toLocaleString?: string | undefined; }) | ({ ...; } & ...还有 1 个 ... & { ...; })> & {...'。参数类型 'ctx' 和 'ctx' 不兼容。类型 'SetupContext<string[]>' 不可分配给类型 'SetupContext <{}>'。类型“{}”缺少类型“string[]”的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25) : 最后一个重载在这里声明。无效 | {} | 渲染函数 | Promise<...>' 不能分配给类型 '(this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; ... 20 more ...; toLocaleString?: string | undefined; }) | ({ ...; } & ...还有 1 个 ... & { ...; })> & {...'。参数类型 'ctx' 和 'ctx' 不兼容。类型 'SetupContext<string[]>' 不可分配给类型 'SetupContext <{}>'。类型“{}”缺少类型“string[]”的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25) : 最后一个重载在这里声明。无效 | {} | 渲染函数 | Promise<...>' 不能分配给类型 '(this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator | undefined; length?: number | undefined; concat?: string[] | undefined; ... 20 more ...; toLocaleString?: string | undefined; }) | ({ ...; } & ...还有 1 个 ... & { ...; })> & {...'。参数类型 'ctx' 和 'ctx' 不兼容。类型 'SetupContext<string[]>' 不可分配给类型 'SetupContext <{}>'。类型“{}”缺少类型“string[]”的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25) : 最后一个重载在这里声明。} & { [迭代器]?: IterableIterator | 不明确的; 长度?:数字 | 不明确的; 连接?:字符串[] | 不明确的; ... 20 多个 ...; toLocaleString?: 字符串 | 不明确的; }) | ({ ...; } & ... 还有 1 个 ... & { ...; })> & {...'。参数 'ctx' 和 'ctx' 的类型不兼容。类型“SetupContext<string[]>”不可分配给类型“SetupContext<{}>”。类型“{}”缺少类型“string[]”中的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25):声明了最后一个重载这里。} & { [迭代器]?: IterableIterator | 不明确的; 长度?:数字 | 不明确的; 连接?:字符串[] | 不明确的; ... 20 多个 ...; toLocaleString?: 字符串 | 不明确的; }) | ({ ...; } & ... 还有 1 个 ... & { ...; })> & {...'。参数 'ctx' 和 'ctx' 的类型不兼容。类型“SetupContext<string[]>”不可分配给类型“SetupContext<{}>”。类型“{}”缺少类型“string[]”中的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25):声明了最后一个重载这里。参数 'ctx' 和 'ctx' 的类型不兼容。类型“SetupContext<string[]>”不可分配给类型“SetupContext<{}>”。类型“{}”缺少类型“string[]”中的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25):声明了最后一个重载这里。参数 'ctx' 和 'ctx' 的类型不兼容。类型“SetupContext<string[]>”不可分配给类型“SetupContext<{}>”。类型“{}”缺少类型“string[]”中的以下属性:length、pop、push、concat 和 28 个以上。ts(2769) mount.d.ts(22, 25):声明了最后一个重载这里。
所以我决定尝试另一件事,感谢https://vue-test-utils.vuejs.org/api/options.html#context我看到了mocks
选项,所以我用下面的代码替换了 wrapper
const wrapper = shallowMount(ProjectItem, {
props: {
index: 0
},
mocks: {
$store: fakeStore
}
});
我仍然No overload matches this call ...
像以前一样有错误。
包.json
"dependencies": {
"axios": "^0.21.4",
"core-js": "^3.6.5",
"pixi.js": "^6.1.3",
"v-smooth-scroll": "^2.0.0-beta.1",
"vue": "^3.0.0",
"vue-class-component": "^8.0.0-0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
"devDependencies": {
"@types/jest": "^24.0.19",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-unit-jest": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-airbnb": "^5.0.2",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^2.0.0-0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-vue": "^7.0.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.2",
"typescript": "~4.1.5",
"vue-jest": "^5.0.0-0"
}
你能告诉我添加商店的单元测试样本shallowMount()
吗?
更新
存储组件中使用的代码:
import { Project } from "@/domain/store/Project";
import { ProjectsGetters } from "@/store/projects/getters";
import { Options, Vue } from "vue-class-component";
import { useStore } from "vuex";
@Options({
props: {
index: String
}
})
export default class ProjectItem extends Vue {
store = useStore();
index!: string;
projects: Array<Project> = this.store.getters[ProjectsGetters.projects];
skills: string = this.store.getters[ProjectsGetters.skillsFromOneProject](
this.index
);
projectOver(index: number) {
this.projects[index].classname = "line-right";
}
projectLeave(index: number) {
this.projects[index].classname = "line-left";
}
}
解决方案
解决方案
我使用了 vuejs 2 的文档,所以 vuejs 3 的文档在这里:https ://next.vue-test-utils.vuejs.org/guide/advanced/vuex.html#testing-with-a-real-vuex-店铺
这是我的测试
import { shallowMount } from "@vue/test-utils";
import ProjectItem from "@/components/ProjectItem.vue";
import { projects } from "@/store/projects";
import { state } from "@/data/fakeStore/projects";
import Vuex from "vuex";
describe("ProjectItem.vue", () => {
const store = new Vuex.Store({
modules: {
projects: {
namespaced: true,
state,
getters: projects.getters
}
}
});
const wrapper = shallowMount(ProjectItem, {
props: {
index: 0
},
global: {
plugins: [store]
}
});
wrapper.vm.projects = state.projects;
wrapper.vm.skills = state.skills;
it("check initialization data", () => {
expect(wrapper.vm.projects).toEqual(state.projects);
expect(wrapper.vm.skills).toEqual(state.skills);
expect(wrapper.vm.index).toEqual(0);
});
});
推荐阅读
- reactjs - 沿圆圈均匀对齐进度条
- javascript - 如何在没有 onDBLClick 的情况下制作第二个 onclick()
- html - 为什么这段代码不能帮助我实现一个空白井字游戏板?
- jquery - 网站出现 508 错误,但我在任何地方都找不到
- electron - electron-builder 构建过程中 buildResources 文件夹的目的是什么?
- android - Android资源传递给函数时的不同值
- python - 按列有效地对事件日志数据库进行分类
- android - Import Github repositories button disabled when go to import github repo in jFrog/Bintray to upload library
- python - ModuleNotFoundError 导入和使用 keras/tensorflow
- r - 如何使用序列中的值作为新变量名有条件地重命名数据框的多列?