如何测试 Vue "Services" 安装到 root,通过 Vue.prototype 访问

How to test Vue "Services" mounted to root, accessed via Vue.prototype

首先,我想解释一下,我有一个 Vue 组件存储库,负责显示从 http 服务检索到的数据。而不是组件本身管理每个实例的相同数据检索并向客户端发送网络请求垃圾邮件,我设法找到了一个允许将另一个组件直接安装到根目录的解决方案(我将其称为“服务”由于它类似于 Angular) 来管理这些组件所需的数据。这很好用,其他组件可以通过 Vue.prototype(通过 this.$TestService.value)访问它。它有一些注意事项,但在大多数情况下,它完全满足了我的需要。这可能并不常见,但那些使用 Vuex 的人正在使用类似的方法,我不想使用商店范式。

我制作了一个非常简单的 Vue JsFiddle 来展示它的实际效果...

https://jsfiddle.net/spronkets/8v31tcfd/18

现在,直截了当...我正在使用 @testing-library/vue@vue/test-utils 和 Jest 来测试组件并获得测试覆盖率,现在我随时都会遇到错误 运行 由于在测试执行期间 Vue.prototype 上不存在该服务而导致的测试。我不想模拟“服务”层的功能,所以有人有解决方案来测试这些根安装组件吗?我已经尝试手动导出服务(卸载和安装)并将它们包含在模拟部分以及将文件直接导入测试文件但是当组件试图检索值时“服务”总是未定义并且仅在测试执行期间...

我还创建了一个简单的存储库,该存储库仿照我在下面使用的 Vue 组件存储库...

https://github.com/kcrossman/VueServiceExample

要开始,请克隆存储库并按照存储库中包含的 README.md 进行操作。谢谢!

如果真正的服务是异步的,我会反对使用它,但如果你只是想注册它以使其可用,你可以按照 mock 说明进行操作,而不是使用对象进行模拟,只需导入真正的服务。虽然在看到你的 TestService 实现后你需要将真正的服务从服务注册中分离出来并导出它才能在本地 vue 中注册它。

您需要创建在您的测试中准备您的自定义 Vue 实例,以便在您的单元测试中使用任何自定义功能(例如商店、路由器和其他任何东西)。 (您可以将您的真实模块与自定义实例一起使用,不必模拟任何东西。)

在您的情况下,您应该使用来自“@vue/test-utils”的“createLocalVue”函数创建一个新的 Vue 实例,并在其上应用您的自定义原型功能。之后,您还可以编写适当的测试用例来访问该自定义功能。

更新: 对于那些将来可能会提到这个的人,Vue 插件可能是这种功能的更好解决方案。


我在 GitHub 中偶然发现了这个问题,这导致我在下面进行了修复:

https://github.com/testing-library/vue-testing-library/issues/113

具体来说,用户的评论 nikravi:

ok, I found the fix. The trick was to add

import Vue from "vue";
import Vuetify from "vuetify";
Vue.use(Vuetify);

and then the render() works without warnings.

我在单元测试中直接手动导入Vue并设置Vue.prototype.$TestService = TestService后,就通过了那个错误。就我个人而言,我认为这很愚蠢,但它奏效了。

在这个工作之后,我还发现你可以在 render 回调中直接访问 Vue 实例(来自 @testing-library/vue),所以我完成了这段代码而不是导入 Vue:

render(TestComponent, {}, vue => {
    vue.prototype.$TestService = TestService;
});

我已经在我之前发布的回购协议中包含了解决我的问题的所有提交:

https://github.com/kcrossman/VueServiceExample

一些测试格式不正确,但在我进行了这些更改后,测试开始起作用,并且我更新了一些其他文件,以便更好地供人们参考。