一、测试DOM
1.操作DOM
简单例子:
/**
* 移除节点
* @param {DOM} node
*/
Pencil.removeNode = node => {
return node.parentNode.removeChild(node)
}
/**
* 绑定事件
*/
Pencil.on = (node,type,handle) => {
node.addEventListener(type,handle,false)
}
describe('test node',()=>{
test('remove node',()=>{
document.body.innerHTML = '<div id="p"><p id="c"></p></div>'
const p = document.getElementById('p')
expect(p.nodeName.toLowerCase()).toBe('div')
const c = document.getElementById('c')
Pencil.removeNode(c)
expect(document.getElementById('c')).toBeNull()
})
})
describe('test on',()=>{
test('on',()=>{
document.body.innerHTML = '<div id="p"><button id="c">点击</button></div>'
const btn = document.getElementById('c')
Pencil.on(btn,'click',()=>{
btn.innerHTML = 'clicked!'
})
btn.click() //模拟点击
expect(btn.innerHTML).toBe('clicked!')
})
})
- 使用
npx jest
测试执行,结果为passed
2.测试DOM原理
- Jest能做 DOM 操作,是因为内置了
JSDOM
-
JSDOM
是一套模拟的 DOM 环境,在node
上运行 - 如果可以的话,
Chrome headless
是比JSDOM
更好的选择
3.测试 Radio 组件
- 测试只能测试逻辑(是否包含某类名或属性)
-
例:
1. radio.html
<div id="radio" class="radio">
<span class="case"><span class="letter">B</span></span>
<span class="case"><span class="letter">I</span></span>
<span class="case"><span class="letter">U</span></span>
</div>
2. ../js/radio.js(组件逻辑)
function Radio(options) {
const def = {
boxId:'',
active: 0,
activeClass: 'radio-active'
}
// 重点!初始化
const opts = this.opts = Object.assign({},def,options)
const box = this.box = document.getElementById(opts.boxId)
this.case = box.querySelectorAll('.case')
this.letter = box.querySelectorAll('.letter')
this.unactive()
this.active(opts.active)
this.events()
}
Radio.prototype.active =function(active){
let cur = this.current
if(typeof cur==='number') {
this.case[cur].classList.remove(this.opts.activeClass)
this.letter[cur].classList.remove(this.opts.activeClass)
}
this.case[active].classList.add(this.opts.activeClass)
this.letter[active].classList.add(this.opts.activeClass)
this.current = active
}
Radio.prototype.unactive = function(){
const len=this.letter.length
for(var i=0;i<len;i++){
this.case[i].classList.remove(this.opts.activeClass)
}
}
Radio.prototype.events = function(){
const self = this
for(var i = 0,len=this.case.length;i<len;i++){
const casei = self.case[i]
casei.order = i
casei.addEventListener('click',function(){
self.active(this.order)
},false)
}
}
module.exports = Radio
// 以上若有修改属性的操作可写为[例]:this.case[i].style.display = 'none'
- 使用
npx jest
测试执行,结果为passed
3. ../test/radio.js(测试用例)
const Radio = require('../js/radio')
const fs = require('fs')
const path = require('path')
test('Radio',()=>{
// 重点!同步加载页面
document.body.innerHTML = fs.readFileSync(path.resolve(__dirname,'./assert/radio.html'))
const radio = new Radio({
boxId:'radio'
})
expect(radio.case[0].classList.contains('radio-active')).toBe(true)
expect(radio.case[1].classList.contains('radio-active')).toBe(false)
expect(radio.case[2].classList.contains('radio-active')).toBe(false)
})
test('Radio click',()=>{
document.body.innerHTML = fs.readFileSync(path.resolve(__dirname,'./assert/radio.html'))
const radio = new Radio({
boxId:'radio'
})
radio.case[2].click()
expect(radio.case[0].classList.contains('radio-active')).toBe(false)
expect(radio.case[1].classList.contains('radio-active')).toBe(false)
expect(radio.case[2].classList.contains('radio-active')).toBe(true)
})
- 使用
npx jest
测试执行,结果为passed
二、测试异步
- 通过使用
done
实现
简单例子:
function delay(callback){
setTimeout(()=>{
callback('give you data')
},1000)
}
test('async',(done)=>{
delay((data)=>{
expect(data).toBe('give you data')
done()
})
})
- 使用
npx jest
测试执行,结果为passed