Vue.js(Mocha / Chai / Sinon)组件单元测试期望失败

时间:2017-09-19 08:15:12

标签: unit-testing vue.js vuex mocha-webpack

我正在尝试测试一个组件(Mocha / Chai / Sinon框架),但是我得到一个断言错误,我找不到为什么它会引发这个错误.. 我想在'input.dispatchEvent(enterEvent)'被触发后我错过了什么...

    1) should change the title
         ChangeTitleComponent.vue changeTitle
         AssertionError: expected commit to have been called with arguments changeTitle, { id: "1", title: "My New Title" }
        at Context.<anonymous> (webpack:///test/unit/specs/components/ChangeTitleComponent.spec.js:40:40 <- index.js:17914:51

ChangeTitleComponent.spec.js

    import Vue from 'vue'
    import ChangeTitleComponent from '@/components/ChangeTitleComponent'
    import store from '@/vuex/store'

    describe('ChangeTitleComponent.vue', () => {
      describe('changeTitle', () => {
        var component

        beforeEach(() => {
          var vm = new Vue({
            template: '<change-title-component :title="title" :id="id" ref="changetitlecomponent">' +
            '</change-title-component></div>',
            components: {
              ChangeTitleComponent
            },
            props: ['title', 'id'],
            store
          }).$mount()
          component = vm.$refs.changetitlecomponent
        })

        it('should change the title', () => {
          // stub $emit method
          sinon.stub(store, 'commit')
          // stub store's dispatch method
          sinon.stub(store, 'dispatch')

          // check component label text
          expect(component.$el.textContent).to.equal('Change the title of your shopping list here ')

          let newTitle = 'My New Title'
          // simulate input Enter event
          const input = component.$el.querySelector('input')
          input.value = newTitle
          const enterEvent = new window.Event('keypress', { which: 13 })
          input.dispatchEvent(enterEvent)
          component._watcher.run()

          // TESTING ACTION: store.commit(types.CHANGE_TITLE, data)
          expect(store.commit).to.have.been.calledWith('changeTitle', {title: newTitle, id: '1'})

          // TESTING ACTION: store.dispatch('updateList', data.id)
          expect(store.dispatch).to.have.been.calledWith('updateList', '1')

          store.dispatch.restore()
          component.commit.restore()
        })
      })
    })

ChangeTitleComponent.vue

    <template>
      <div>
        <em>Change the title of your shopping list here</em>
        <input :value="title" @input="onInput({ title: $event.target.value, id: id })"/>
      </div>
    </template>

    <script>
      import { mapActions } from 'vuex'

      export default {
        props: ['title', 'id'],
        methods: mapActions({  // dispatching actions in components
          onInput: 'changeTitle'
        })
      }
    </script>

vuex / actions.js

    import * as types from './mutation_types'
    import api from '../api'
    import getters from './getters'

    export default {

      changeTitle: (store, data) => {
        store.commit(types.CHANGE_TITLE, data)
        store.dispatch('updateList', data.id)
      },
      updateList: (store, id) => {
        let shoppingList = getters.getListById(store.state, id)
        return api.updateShoppingList(shoppingList)
        .then(response => {
          return response
        })
        .catch(error => {
          throw error
        })
      }

    }

vuex / mutations.js

    import * as types from './mutation_types'
    import getters from './getters'
    import _ from 'underscore'

    export default {
      [types.CHANGE_TITLE] (state, data) {
        getters.getListById(state, data.id).title = data.title
      }
    }

vuex / mutation_types.js

    export const CHANGE_TITLE = 'CHANGE_TITLE'

1 个答案:

答案 0 :(得分:0)

我决定使用'avoriaz'(npm install --save-dev avoriaz)作为单元测试框架,我想我的测试非常完整。它涵盖了100%的组件代码,测试道具方法。 动作的代码已经过测试,所以我只需要检查输入触发器..

但是,如果有必要更新此答案,欢迎任何反馈

    import Vue from 'vue'
    import ChangeTitleComponent from '@/components/ChangeTitleComponent'
    import Vuex from 'vuex'

    import sinon from 'sinon'
    import { mount } from 'avoriaz'

    Vue.use(Vuex)

    describe('ChangeTitleComponent.vue', () => {
      let actions
      let store

      beforeEach(() => {
        actions = {
          changeTitle: sinon.stub()
        }
        store = new Vuex.Store({
          state: {},
          actions
        })
      })

      describe('check component', () => {
        it('testing props', () => {
          const wrapper = mount(ChangeTitleComponent)
          wrapper.setProps({id: '1'})
          wrapper.setProps({title: 'Groceries'})
          expect(wrapper.vm.$props.id).to.equal('1')
          expect(wrapper.vm.$props.title).to.equal('Groceries')
        })

        it('calls store action changeTitle when input value is: New Title and an input event is fired', () => {
          const wrapper = mount(ChangeTitleComponent, { store })
          const input = wrapper.find('input')[0]
          input.element.value = 'New Title'
          input.trigger('input')
          expect(actions.changeTitle.calledOnce).to.equal(true)
        })
      })
    })