问题描述
我不明白为什么会有一个突变: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 单元测试突变:无法完成功能测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!