Vue單元測試---Karma+Mocha+Chai實踐

本文基於vue-webpack-boilerplate。官方推薦使用Karma+Mocha+Chai來進行單元測試。html

介紹

Karma:一個測試運行器,用於啓動瀏覽器,運行測試案例並將結果報告給咱們。該工具的主要做用是將項目運行在各類主流Web瀏覽器進行測試。vue

Mocha:一個測試框架。可結合chai斷言庫使用。webpack

Chai:一個測試斷言庫,提供了更好的斷言語法。所謂斷言,就是對組件作一些操做,並預言產生的結果。若是測試結果與斷言相同則測試經過。Chai斷言庫中,to be been is that which and has have with at of same but does這些語言鏈是沒有意義的,只是便於理解而已。git

實踐

組件無依賴,無props

對於無需導入任何依賴,也沒有props的,直接編寫測試案例便可。npm

MyComponent.vueapi

<template>
  <span>{{ message }}</span>
</template>
<script>
  export default {
    data () {
      return {
        message: 'hello!'
      }
    },
    created () {
      this.message = 'bye!'
    }
  }
</script>

MyComponent.spec.js瀏覽器

// 導入 Vue.js 和組件,進行測試
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'

describe('MyComponent', () => {
  // 檢查原始組件選項
  it('has a created hook', () => {
    expect(typeof MyComponent.created).to.eql('function')
  })
})

組件有props

對於組件須要props,編寫單元測試時,經過propsData傳遞該參數。框架

MyComponent.vue

<template>
  <p>{{ msg }}</p>
</template>
<script>
  export default {
    props: ['msg']
  }
</script>

MyComponent.spec.js

import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'

function getRenderedText (Component, propsDataMsg) {
  const Ctor = Vue.extend(Component)
  const vm = new Ctor({ propsData: propsDataMsg}).$mount()
  return vm.$el.textContent
}
describe('MyComponent', () => {
  it('renders correctly with different props', () => {
    expect(getRenderedText(MyComponent, {
      msg: 'Hello'
    })).to.eql('Hello')
    expect(getRenderedText(MyComponent, {
      msg: 'Bye'
    })).to.eql('Bye')
  })
})

組件有依賴

若組件存在依賴,則可經過inject-loader解決。inject-loader可將任意依賴項注入到*.vue組件中。

MyComponent.vue

<template>
  <div class="msg">{{ msg }}</div>
</template>

<script>
// this dependency needs to be mocked
import SomeService from '../service'

export default {
  data () {
    return {
      msg: SomeService.msg
    }
  }
}
</script>

MyComponent.spec.js

//「!!」表示禁用全局配置的全部loaders。「vue-loader?inject!」表示使用vue-loader,傳入inject參數。
const ExampleInjector = require('!!vue-loader?inject!./example.vue')
//運行ExampleInjector函數返回一個MyComponent的實例,該實例中MyComponent組件的依賴項已被模擬。
const ExampleWithMocks = ExampleInjector({
  // mock it
  '../service': {
    msg: 'Hello from a mocked service!'
  }
})

describe('MyComponent', () => {
  it('should render', () => {
    const vm = new Vue({
      template: '<div><test></test></div>',
      components: {
        'test': ExampleWithMocks
      }
    }).$mount()
    expect(vm.$el.querySelector('.msg').textContent).to.eql('Hello from a mocked service!')
  })
})

異步操做

對於異步操做,it塊執行的時候,須要傳入一個回調函數,一般該函數被命名爲done。當測試結束的時候,必須顯式調用這個函數,告訴Mocha測試結束了。不然,Mocha就沒法知道,測試是否結束,會一直等到超時報錯。

// 在狀態更新後檢查生成的 HTML
it('updates the rendered message when vm.message updates', done => {
  const vm = new Vue(MyComponent).$mount()
  vm.message = 'foo'
  // 在狀態改變後和斷言 DOM 更新前等待一刻
  Vue.nextTick(() => {
    expect(vm.$el.textContent).to.eql('foo')
    done()
  })
})

npm run unit

執行 npm run unit 命令運行單元測試。會產生結果列表:

clipboard.png

若想看測試覆蓋率等狀況,可在test/unit/coverage查看。

注意

  • 測試腳本都放在 test/unit/specs/ 目錄下。

  • 腳本命名方式是[組件名].spec.js。

  • 在karma.conf.js文件裏修改karma配置。

  • 單元測試默認測試 src 目錄下除了 main.js 以外的全部文件,可在 test/unit/index.js 文件中修改。

  • 測試腳本里面應該包括一個或多個describe塊,每一個describe塊應該包括一個或多個it塊。

    • describe塊稱爲"測試套件"(test suite),表示一組相關的測試。它是一個函數,第一個參數是測試套件的名稱("加法函數的測試"),第二個參數是一個實際執行的函數。

    • it塊稱爲"測試用例"(test case),表示一個單獨的測試,是測試的最小單位。它也是一個函數,第一個參數是測試用例的名稱("1 加 1 應該等於 2"),第二個參數是一個實際執行的函數。

  • Mocha在describe塊之中,提供測試用例的四個鉤子:before()、after()、beforeEach()和afterEach()。它們會在指定時間執行。

參考:
單元測試
Testing with Mocks
Unit Testing
測試框架 Mocha 實例教程
Chai

相關文章
相關標籤/搜索