如何测试通过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上不存在服务。我不想模拟“服务”层的功能,那么有人有解决方案来测试这些根目录安装的组件吗?我尝试过手动导出服务(卸载和挂载),并将它们包括在模拟部分中,以及将文件直接导入测试文件中,但是当组件尝试检索值时,“ Service”始终是未定义的,并且仅在测试执行期间...

我还创建了一个以我正在使用的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

某些测试的格式有误,但是一旦我进行了更改,这些测试就开始起作用,并且我更新了一些其他文件,以便于人们参考。