單元測(cè)試
主要測(cè)試的是樣式,功能,組件,流程,也包含判斷特定條件,某個(gè)場(chǎng)景下函數(shù)的行為
前端單元測(cè)試目的
- 反饋功能輸出
- bug
- 重構(gòu)安全性
- 協(xié)作開發(fā)
如何進(jìn)行單元測(cè)試
被測(cè)試對(duì)象:最小組成單元: 函數(shù),方法,類;可以孤立的驗(yàn)證
// 被測(cè)試對(duì)象
let add = (a,b)=>a+b;
let res = add(1,2);
if(res!==3){
throw new Error('預(yù)期值與實(shí)際值不一致');
}
let add = (a, b) => a + b; // 被測(cè)試對(duì)象
let expect = (res) => {
return {
toBe: (actual) => {
if (res !== actual) {
throw new Error('預(yù)期與結(jié)果不同')
}
}
}
}
let test = (desc, fn) => {
try {
fn()
} catch (e) {
console.log('沒有通過')
}
}
test('加法測(cè)試', () => {
expect(add(1, 2)).toBe(1)
})
第三方庫jest
npm i jest -D 安裝命令
npm ls jest 查看是否生效
match.js
let add = (a, b) => a + b;
module.exports={add}
match.test.js
let add = require('./match')
test('a+b加法測(cè)試',()=>{
expect(add(1,2)).toBe(2)
})
執(zhí)行npm run jest進(jìn)行單元測(cè)試
函數(shù)式編程
- 命令式編程
詳細(xì)的命令機(jī)器怎么去處理一件事情以達(dá)到你想要的結(jié)果 - 函數(shù)式編程
函數(shù)式編程是一種編程范式,是一種構(gòu)建計(jì)算機(jī)程序結(jié)構(gòu)和元素的風(fēng)格,把計(jì)算看做對(duì)數(shù)學(xué)函數(shù)的評(píng)估,避免了狀態(tài)的變化和數(shù)據(jù)的可變。
// 數(shù)組每一項(xiàng)比之前自增1,以下寫法是命令式編程,復(fù)用性比較低,僅能自增1
let newArr = (arr)=>{
let res = [];
for(i=0;i<arr.length;i++){
res.push(arr[i]+1)
}
return res
}
console.log(newArr([1,2,3,4]));
// 函數(shù)式編程,將程序分解為一些更可重用、更可靠更易分解的部分,然后將他們組合起來
let arr = [1, 2, 3, 4]
let newArr = (arr,fn) => {
let res = [];
for (let i = 0; i < arr.length; i++) {
res.push(fn(arr[i]))
}
return res
}
let add = item => item + 5
console.log(newArr(arr, add))
純函數(shù)
函數(shù)調(diào)用的參數(shù)相同,則永遠(yuǎn)返回相同的結(jié)果,不依賴程序執(zhí)行期間函數(shù)外部任務(wù)狀態(tài)或者數(shù)據(jù)的變化,必須只依賴于其輸入的參數(shù)。
// 不是純函數(shù)
let discount = 0.8;
let calculatePrice = (price)=>price*discount;
let price = calculatePrice (100);
console.log(price);
// 不純的函數(shù)
const foo = (something)=>{
const dt = new Date().toString();
console.log(`${dt}:${something}`);
return something;
}
foo('hello');
// 不純的API
let arr=[1,2,3,4,5,6];
arr.slice(1,2); //純函數(shù) 返回[2,3],原函數(shù)不會(huì)發(fā)生變化
arr.splice(1,3);// 非純函數(shù),返回[2,3,4],原數(shù)組改變
arr.pop();// 非純函數(shù),返回6,原數(shù)組改變
// 純函數(shù),相同的輸入,永遠(yuǎn)會(huì)得到相同的輸出
let calculatePrice = (price,discount )=>price*discount;
let price = calculatePrice (100,0.7);
console.log(price);
函數(shù)的副作用
當(dāng)調(diào)用函數(shù)時(shí),除了返回函數(shù)值之外,還對(duì)主調(diào)用函數(shù)產(chǎn)生附加的影響
例如修改全局變量(函數(shù)外 的變量)或修改參數(shù)
let a =5;
let foo=()=>a=a*5;
foo();
console.log(a);
如何保證函數(shù)無副作用
- 函數(shù)入口使用參數(shù)運(yùn)算,而不修改它
- 函數(shù)內(nèi)不修改函數(shù)外的變量
- 運(yùn)算結(jié)果通過函數(shù)返回給外部
let data={count:1};
let foo=(data)=>{
data.count = 5;
}
console.log(data.count); // 1
foo(data);
console.log(data.count); // 5
// 改進(jìn)方案
let data={count:1};
let foo=(data)=>{
// 深拷貝
let data1={...data}; // 或者使用JSON.stringify(data)
data1.count = 5;
}
console.log(data.count); // 1
foo(data);
console.log(data.count); // 1
可變性是指創(chuàng)建以后可以任意修改
不可變性指一個(gè)變量,一旦創(chuàng)建,就永遠(yuǎn)不會(huì)發(fā)生改變,不可變性是函數(shù)式編程的核心概念