Vues.js单元测试突变:无法完成功能测试

时间:2017-09-29 06:48:36

标签: unit-testing vue.js

我不明白为什么突变:tick(状态)范围功能未经过测试...反馈欢迎

mutations.spec.js

    import Vue from 'vue'
    import mutations from '@/vuex/mutations'
    import * as types from '@/vuex/mutation_types'
    import { WORKING_TIME, RESTING_TIME, KITTEN_TIME } from '@/config'

    describe('mutations', () => {
      var state

      beforeEach(() => {
        state = {}
        // we don't need to test the plugin's functionality
        // let's mock Vue noise plugin to be able to listen on its methods
        Vue.noise = {
          start: () => {},
          stop: () => {},
          pause: () => {}
        }
        sinon.spy(Vue.noise, 'start')
        sinon.spy(Vue.noise, 'pause')
        sinon.spy(Vue.noise, 'stop')
      })
      afterEach(() => {
        Vue.noise.start.restore()
        Vue.noise.pause.restore()
        Vue.noise.stop.restore()
      })

      describe('START', () => {
        it('should set all the properties correcly after start', () => {
          // ensure that all the state properties are undefined
          // before calling the start method
          expect(state.started).to.be.undefined
          expect(state.stopped).to.be.undefined
          expect(state.paused).to.be.undefined
          expect(state.interval).to.be.undefined
          expect(state.counter).to.be.undefined
          // call the start method
          mutations[types.START](state)
          // check that all the properties were correctly set
          expect(state.started).to.be.true
          expect(state.stopped).to.be.false
          expect(state.paused).to.be.false
        })
        it('should call Vue.noise.start method if both state.isWorking and state.soundEnabled are true', () => {
          state.isWorking = true
          state.soundEnabled = true
          mutations[types.START](state)
          expect(Vue.noise.start).to.have.been.called
        })
        it('should not call Vue.noise.start method if state.isWorking is true', () => {
          state.isWorking = false
          state.soundEnabled = true
          mutations[types.START](state)
          expect(Vue.noise.start).to.not.have.been.called
        })
        it('should not call Vue.noise.start method if state.soundEnabled is true', () => {
          state.isWorking = true
          state.soundEnabled = false
          mutations[types.START](state)
          expect(Vue.noise.start).to.not.have.been.called
        })
      })
    })

在日志中,我的测试代码行永远不会显示...

console.log('TICK: ', state.counter) // <= NEVER DISPLAYED

的console.log

    yves$ npm run unit

    > pomodoro@1.0.0 unit /Users/yves/Developments/pomodoro
    > cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run

    [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/
    [launcher]: Launching browser ChromeHeadless with unlimited concurrency
    [launcher]: Starting browser ChromeHeadless
    [HeadlessChrome 0.0.0 (Mac OS X 10.12.6)]: Connected on socket lqjww0M5006nHAlqAAAA with id 17876235
    LOG LOG: 'START mutation'
    LOG LOG: 'GOING TO SET INTERVAL W TICK'
    LOG LOG: 'STATE INTERVAL IS NOW: ', 5

    mutations
        START
          ✓ should set all the properties correcly after start
    LOG LOG: 'START mutation'
    LOG LOG: 'GOING TO SET INTERVAL W TICK'
    >>> should be displayed here
    LOG LOG: 'STATE INTERVAL IS NOW: ', 6
          ✓ should call Vue.noise.start method if both state.isWorking and state.soundEnabled are true
    LOG LOG: 'START mutation'
    LOG LOG: 'GOING TO SET INTERVAL W TICK'
    >>> should be displayed here
    LOG LOG: 'STATE INTERVAL IS NOW: ', 7
          ✓ should not call Vue.noise.start method if state.isWorking is true
    LOG LOG: 'START mutation'
    LOG LOG: 'GOING TO SET INTERVAL W TICK'
    >>> should be displayed here
    LOG LOG: 'STATE INTERVAL IS NOW: ', 8
          ✓ should not call Vue.noise.start method if state.soundEnabled is true

mutation.js

    import * as types from './mutation_types'
    import _ from 'underscore'
    import { WORKING_TIME, RESTING_TIME, KITTEN_TIME } from '../config'
    import Vue from 'vue'

    function togglePomodoro (state, toggle) {
      console.log('TOGGLEPomodoro: ', toggle)
      if (_.isBoolean(toggle) === false) {
        toggle = !state.isWorking
      }
      state.isWorking = toggle
      console.log('state.isWorking: ', toggle)
      if (state.isWorking) {
        Vue.noise.start()
      } else {
        Vue.noise.pause()
      }
      state.counter = state.isWorking ? WORKING_TIME : RESTING_TIME
    }

    function tick (state) {
      console.log('TICK: ', state.counter) // <= NEVER DISPLAYED
      if (state.counter === 0) {
        togglePomodoro(state)
      }
      state.counter--
      if (state.counter % KITTEN_TIME === 0) {
        state.timestamp = new Date().getTime()
      }
    }

    export default {
      [types.START] (state) {
        console.log('START mutation')
        state.started = true
        state.paused = false
        state.stopped = false
        console.log('GOING TO SET INTERVAL W TICK')
        state.interval = setInterval(() => tick(state), 1000) // HOW CAN I CHECK IT ?
        console.log('STATE INTERVAL IS NOW: ', state.interval)
        if (state.isWorking && state.soundEnabled) {
          Vue.noise.start()
        }
      }
    }

1 个答案:

答案 0 :(得分:0)

解决方案是使用lolex包(计时器API的JavaScript实现)

npm install --save-dev lolex

然后在我的spec文件中伪造计时器功能 1 - 使用lolex

 var lolex = require('lolex')

2 - 创建时钟

describe('mutations', () => {
  let state
  let clock

  beforeEach(() => {
    clock = lolex.createClock()
    state = {}
    ....

3 - 测试工作开关 - &gt; 10秒后的休息时间 (工作,休息时间在导入到mutation.js的config.js文件中定义。为了测试目的,我必须缩短它们...也许可以定义一个特定的config.test.js文件??)

使用clock.setTimeout(回调,延迟)...所以mut.js的tick(state)函数被调用...它必须在导出/导入之前

  describe('TOGGLE WORKING->REST', () => {
    it('should switch to REST period after 5 sec', () => {
      state.isWorking = true
      state.soundEnabled = true
      state.interval = clock.setInterval(() => tick(state), 1000)
      mutations[types.START](state)
      expect(Vue.noise.start).to.have.been.called
      state.counter = 0
      // delay clock
      clock.setTimeout(() => {
        expect(state.isWorking).to.equal(false)
      }, 5000)
    })
  })

4 - 从Rest测试开关 - &gt;工作期间,在timeOut()之前使用click.tick()来改变工作状态 - &gt;

之前休息
 it('should switch back to WORK period after 10 sec', () => {
    state.isWorking = true
    state.soundEnabled = true
    state.interval = clock.setInterval(() => tick(state), 1000)
    mutations[types.START](state)
    expect(Vue.noise.start).to.have.been.called
    state.counter = 0
    clock.tick(5000) // switch to REST period
    // delay clock
    clock.setTimeout(() => {
      expect(state.isWorking).to.equal(false)
    }, 5000)
  })

etvoilà...感谢lolex ..