Vue.js变异单元测试w sinonjs / lolex为什么我的setInterval()回调函数没有被执行

时间:2017-10-07 12:42:08

标签: unit-testing vue.js sinon

我正在尝试测试我的mutation.js文件;测试是正确执行但是看了覆盖范围,有一个函数(tick())没有被覆盖,因为它从未从规范中调用过......

注意:我正在使用sinonjs / lolex模拟传球时间

mutation.spec.js

import Vue from 'vue'
import mutations, { tick } from '@/vuex/mutations'
import * as types from '@/vuex/mutation_types'

import { WORKING_TIME, RESTING_TIME } from '@/config'

const lolex = require('lolex') //JS implementation of timer APIs

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

  beforeEach(() => {
    clock = lolex.createClock()
    state = {}
    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('TOGGLE WORKING->REST->WORKING', () => {
    it('should switch to REST period after WORKING then back WORKING after RESTING', () => {
      state.isWorking = true
      state.soundEnabled = true

      // IT SHOULD CALL THE TICK() imported method to cover it !
      state.interval = clock.setInterval(() => tick(state), 1000)
      console.log('STATE INTERVAL: ', state.setInterval)
      // console LOG: 'STATE INTERVAL: ', undefined

      state.counter = 0
      mutations[types.START](state)
      expect(Vue.noise.start).to.have.been.called
      clock.setTimeout(() => {
        // should be resting now
        expect(state.isWorking).to.equal(false)
        clock.setTimeout(() => {
          // should be back working now
          expect(state.isWorking).to.equal(true)
        }, WORKING_TIME + RESTING_TIME)
      }, WORKING_TIME)
    })
  })
})

vuex / 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) {
      if (_.isBoolean(toggle) === false) {
        toggle = !state.isWorking
      }
      state.isWorking = toggle
      if (state.isWorking) {
        Vue.noise.start()
      } else {
        Vue.noise.pause()
      }
      state.counter = state.isWorking ? WORKING_TIME : RESTING_TIME
    }

    export function tick (state) {
      console.log('tick called')
      if (state.counter === 0) {
        togglePomodoro(state)
      }
      state.counter--
      if (state.counter % KITTEN_TIME === 0) {
        state.timestamp = new Date().getTime()
      }
    }

    export default {
      [types.START] (state) {
        state.started = true
        state.paused = false
        state.stopped = false
        state.interval = setInterval(() => tick(state), 1000)
        if (state.isWorking && state.soundEnabled) {
          Vue.noise.start()
        }
      },
    }

1 个答案:

答案 0 :(得分:1)

使用lolex进行了严格的测试!应写成如下(使用clock.install()和clock.tick():

import Vue from 'vue'
import mutations from '@/vuex/mutations'
import * as types from '@/vuex/mutation_types'

import { WORKING_TIME, RESTING_TIME } from '@/config'

const lolex = require('lolex') // JavaScript implementation of the timer APIs

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

  beforeEach(() => {
    clock = lolex.install()
    state = {}
    Vue.noise = {
      start: () => {},
      ...
      ...
    }
    sinon.spy(Vue.noise, 'start')
    ...
    ...
  })
  afterEach(() => {
    Vue.noise.start.restore()
    ...
    ...
  })


  describe('TOGGLE WORKING->REST->WORKING', () => {
    it('should switch to REST period after WORKING then back WORKING after RESTING', () => {
      state.isWorking = true
      state.soundEnabled = true
      state.counter = 0
      mutations[types.START](state)
      // console.log('STATE WORKING: ', JSON.stringify(state))
      expect(Vue.noise.start).to.have.been.called
      // should be back working now
      expect(state.isWorking).to.equal(true)
      clock.tick(WORKING_TIME * 1000)
      // console.log('STATE RESTING: ', JSON.stringify(state))
      // should be resting now
      expect(state.isWorking).to.equal(false)
      clock.tick(RESTING_TIME * 1000)
      // console.log('STATE WORKING: ', JSON.stringify(state))s
    })
  })
})