簡體   English   中英

Vue.js 過濾器和測試

[英]Vue.js filters and testing

我使用 vue-cli 創建示例項目vue init webpack my-test3 ,並選擇同時包含 e2e 和單元測試。

問題 1:根據模板過濾器的文檔,我嘗試在main.js中添加新的過濾器:

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

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})

還有我的App.vue

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <hello></hello>
    <world></world>

    <div class="test-test">{{ 'tesT' | capitalize }}</div>
  </div>
</template>

<script>
import Hello from './components/Hello'
import World from './components/World'

export default {
  name: 'app',
  components: {
    Hello,
    World
  }
}
</script>

我收到警告(錯誤):

[Vue 警告]:無法解析過濾器:大寫(在組件 <app> 中找到)

如果我在初始化新的 Vue 應用程序之前修改main.js以注冊過濾器,那么它可以正常工作。

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

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

為什么一個有效而另一個無效?

問題 2:通過上面的例子Vue.filter(... ,我為World.vue組件添加了一個測試:

<template>
  <div class="world">
    <h1>{{ msg | capitalize }}</h1>
    <h2>{{ desc }}</h2>

    Items (<span>{{ items.length }}</span>)
    <ul v-for="item in items">
        <li>{{ item }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'world',
  data () {
    return {
      msg: 'worldly App',
      desc: 'This is world description.',
      items: [ 'Mon', 'Wed', 'Fri', 'Sun' ]
    }
  }
}
</script>

World.spec.js

import Vue from 'vue'
import World from 'src/components/World'

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

describe('World.vue', () => {
  it('should render correct title', () => {
    const vm = new Vue({
      el: document.createElement('div'),
      render: (h) => h(World)
    })
    expect(vm.$el.querySelector('.world h1').textContent)
      .to.equal('Worldly App')
  })
  it('should render correct description', () => {
    const vm = new Vue({
      el: document.createElement('div'),
      render: (w) => w(World)
    })
    expect(vm.$el.querySelector('.world h2').textContent)
      .to.equal('This is world description.')
  })
})

為了通過上述測試,我需要包含Vue.filter(...過濾器大寫的定義,否則測試會失敗。所以我的問題是,如何構造過濾器/組件並初始化它們,這樣測試更容易?

我覺得我不應該在單元測試中注冊過濾器,這應該是組件初始化的一部分。 但是,如果組件繼承/使用從主應用程序定義的過濾器,則測試組件將不起作用。

有什么建議、意見、閱讀材料嗎?

一個好的做法是創建一個過濾器文件夾並在此文件夾中的單個文件中定義您的過濾器,如果您想在所有組件中訪問它們,則全局定義所有過濾器,例如:


    // capitalize.js

    export default function capitalize(value) {
      if (!value) return '';
      value = value.toString().toLowerCase();
      value = /\.\s/.test(value) ? value.split('. ') : [value];

      value.forEach((part, index) => {
        let firstLetter = 0;
        part = part.trim();

        firstLetter = part.split('').findIndex(letter => /[a-zA-Z]/.test(letter));
        value[index] = part.split('');
        value[index][firstLetter] = value[index][firstLetter].toUpperCase();
        value[index] = value[index].join('');
      });

      return value.join('. ').trim();
    }

要成功測試它並且如果你使用@vue/test-utils來測試你的單個文件組件,你可以使用createLocalVue來做到這一點,如下所示:

// your-component.spec.js

import { createLocalVue, shallowMount } from '@vue/test-utils';
import capitalize from '../path/to/your/filter/capitalize.js';
import YOUR_COMPONENT from '../path/to/your/component.vue';

describe('Describe YOUR_COMPONENT component', () => {
  const localVue = createLocalVue();

  // this is the key line
  localVue.filter('capitalize', capitalize);

  const wrapper = shallowMount(YOUR_COMPONENT, {
    // here you can define the required data and mocks
    localVue,
    propsData: {
      yourProp: 'value of your prop',
    },
    mocks: {
      // here you can define all your mocks
      // like translate function and others.
    },
  });

  it('passes the sanity check and creates a wrapper', () => {
    expect(wrapper.isVueInstance()).toBe(true);
  });
});

我希望能幫助你。

問候。

我最好的猜測是,如果您在組件內定義filters ,它們將只能在該組件內使用。 在您的情況下,您只能在主 Vue 實例中使用capitalize ,而不是它的子組件。 將其轉移到全球層面解決了這個問題。

對於第二個問題,您在測試文件中添加過濾器定義是正確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM