本文介绍了Vues.js 单元测试突变:无法完成功能测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么会有一个突变:tick(state) 作用域函数没有被测试...欢迎反馈

I don't understand why a mutation: tick(state) scoped function is not tested... feedback welcome

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
        })
      })
    })

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

In the log, the line of my test code is never displayed ...

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

console.log

    yves$ npm run unit

    > [email protected] 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()
        }
      }
    }

推荐答案

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

the solution is to use lolex package ( JavaScript implementation of the timer APIs)

npm install --save-dev lolex

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

and then in my spec file to fake the timer functions1 - using lolex

 var lolex = require('lolex')

2 - 创建时钟

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

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

3 - 测试从工作切换 -> 10 秒后的休息时间(工作,休息时间在导入mutation.js的config.js文件中定义.我必须缩短它们以进行测试......也许可以定义一个特定的config.test.js文件??)

3 - test the switch from Working -> Rest period after 10 sec( working, resting time are defined in the config.js file imported into the mutation.js. I have to shorten them for testing purposes ... maybe it's possible to define a specific config.test.js file ??)

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

using the clock.setTimeout(callback, delay) ... so the tick(state) function of the mutation.js is called... it must be exported/imported before

  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 -> Working period 切换,在 timeOut() 之前使用 click.tick() 将状态从 Working -> Rest just before

4 - Test the switch from Rest -> Working period, using a click.tick() before the timeOut() to change the state from Working -> Rest just before

 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)
  })

等等……感谢 lolex ..

et voilà... thanks to lolex ..

这篇关于Vues.js 单元测试突变:无法完成功能测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 03:15