js單元測(cè)試+函數(shù)式編程

單元測(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ù)式編程的核心概念

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容