【问题标题】:Unit testing vue component, using vue-cli, can't test parent methods?单元测试vue组​​件,使用vue-cli,不能测试父方法?
【发布时间】:2019-03-20 18:14:40
【问题描述】:

我遇到了这个我无法弄清楚的问题,环顾四周似乎找不到任何人问同样的问题......

所以,这是我的工作代码:

main.js:

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

window.Vue = Vue

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  methods: {
    greetings: function () {
      return 'good morning'
    }
  },
  render: h => h(App)
})

路由器/index.js:

import Vue from 'vue'
import Router from 'vue-router'
import Configurations from '@/components/Configurations'

Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/configs',
      name: 'Configurations',
      component: Configurations
    }
  ]
})

App.vue:

<template>
    <router-view></router-view>
</template>
<script>
export default {
  name: "App"
};
</script>

Configurations.vue:

<template>
<span>{{greetings}}</span>
</template>

<script>
export default {
  name: "configurations",
  data() {
    return {
      greetings: ""
    };
  },
  created: function() {
    this.greetings = this.$root.greetings();
  }
};
</script>

当我运行它时,它会显示一个带有“早上好”字样的页面。没有其他的。如您所见,问候消息是在 main.js 文件中定义的,因为在这种情况下,我希望在所有组件上都显示一条消息,即:版权说明。所以我将消息设置在我所有组件的共同祖先上。

据我了解,要从“父”组件调用方法,您可以使用 this.$root.yourMethod() 来调用它。

现在,问题是,如果我想对配置组件运行单元测试,我会收到一个错误,这让我相信我的设置方式,我无法测试 this.$root .greetings() 因为有些东西告诉我测试环境不知道组件之间的父子关系。

所以,当我跑步时:

cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run

已设置以下测试文件:

Configurations.spec.js

import Configurations from '@/components/Configurations'
import Vue from 'vue'

describe('Configurations.vue', () => {
  it('should display a greetings message', () => {
    const Constructor = Vue.extend(Configurations)
    const ConfigurationsComponent = new Constructor().$mount()
    expect(ConfigurationsComponent.greetings).to.not.be.undefined;
  })
})

我明白了:

> 16 10 2018 09:28:35.184:INFO [karma]: Karma v1.7.1 server started at
> http://0.0.0.0:3000/ 16 10 2018 09:28:35.191:INFO [launcher]:
> Launching browser PhantomJS with unlimited concurrency 16 10 2018
> 09:28:35.204:INFO [launcher]: Starting browser PhantomJS 16 10 2018
> 09:28:40.977:INFO [PhantomJS 2.1.1 (Windows 8.0.0)]: Connected on
> socket WnDl-mQqmNZQOfyzAAAA with id 10303480 ERROR LOG: '[Vue warn]:
> Error in created hook: "TypeError:  is not a constructor (evaluating
> 'this.$root.greetings()')"

(后面是更多的行,堆栈溢出不会让我发布,因为它们包含太多链接)

现在,如果我要改变

this.greetings = this.$root.greetings()

收件人:

this.greetings = "good morning";

Configurations.vue 文件中,然后再次运行测试命令,我会得到:

> 16 10 2018 09:48:43.174:INFO [karma]: Karma v1.7.1 server started at
> http://0.0.0.0:3000/ 16 10 2018 09:48:43.180:INFO [launcher]:
> Launching browser PhantomJS with unlimited concurrency 16 10 2018
> 09:48:43.555:INFO [launcher]: Starting browser PhantomJS 16 10 2018
> 09:48:49.228:INFO [PhantomJS 2.1.1 (Windows 8.0.0)]: Connected on
> socket o8BQ24wv1QX26SAZAAAA with id 53463701
> 
>   Configurations.vue
>     √ should display a greetings message
>
> PhantomJS 2.1.1 (Windows 8.0.0): Executed 1 of 1 SUCCESS (0.024 secs / 0.017 secs)
>
> TOTAL: 1 SUCCESS

(后面是一些不相关的信息)

那么,如何对包含 this.$root 方法调用的组件运行单元测试?

感谢任何帮助。

  • 卢卡斯

【问题讨论】:

    标签: javascript unit-testing vue.js vuejs2 vue-cli


    【解决方案1】:

    你应该(几乎)永远不要从父组件调用某些东西。

    您有两种可能性: 1. 使用 vuex 存储并在那里保存您的数据。然后每个需要的组件都可以通过 store getter 访问它。 2. 将所需的数据作为道具提供给您的子组件。

    因为道具东西很快就变得乱七八糟,所以建议使用商店。

    如果您这样做,您的测试将变得更加清晰易读。

    使用模拟商店的简单测试(只是为了展示事情的可能):

    describe('MyComponent', () => {
      let wrapper
    
      beforeEach(() => {
        const localVue = createLocalVue()
        wrapper = mount(MyComponent, {
          localVue,
          mocks: {
            $store: {
              getters: {
                'copyright': 'MyCopyright text'
              }
            }
          }
        })
      })
    
      it('should display copyright text', () => {
        expect(wrapper.text('MyCopyright text')).toBe(true) 
      })
    })
    

    【讨论】:

    • 我明白了。但是对于非常简单的事情没有其他选择吗?我会尝试一下 vuex,但对于简单的事情来说似乎有点矫枉过正。谢谢!
    • 我尝试了您的建议,它运行良好,直到我决定对其进行测试:现在发生了同样的问题,但现在它抱怨 this.$store 而不是 this.$root 我的测试环境只是显然不知道 main.js...
    • 你的环境在单元测试中不应该知道你的 main.js。我用一个模拟商店的简单测试更新了我的答案。它使用 jest 作为测试运行器。
    • 嗨,托马斯,再次感谢。实际上,在您建议 vuex 之后,我再次搜索该主题并找到了答案。这最终帮助了我:stackoverflow.com/questions/42542697/… 该商店现在在我的规范文件中可用,这是我缺少的关键,它与您的建议非常相似。虽然我没有测试你的代码,但我仍然接受你的回答,因为我在正确的轨道上引导我。似乎我还有很多东西要学习单元测试和 vue。谢谢!
    • 最难的一步永远是第一步! ;)
    猜你喜欢
    • 1970-01-01
    • 2019-04-18
    • 2023-01-03
    • 2016-10-19
    • 1970-01-01
    • 2019-06-24
    • 2020-12-02
    • 2019-01-02
    • 1970-01-01
    相关资源
    最近更新 更多