JavaScript 測試教程–part 3:測試 props,掛載函數和快照測試[每日前端夜話0xE9]

  • 2019 年 11 月 25 日
  • 筆記

正文共:1489 字

預計閱讀時間:6 分鐘

作者:Marcin Wanago

翻譯:瘋狂的技術宅

來源:wanago.io

在上一篇教程中,我介紹了使用 Enzyme 測試 React 組件的基礎知識。今天,將進行更深入的研究,並學習如何測試 props,如何(以及為什麼)使用 mount 函數以及什麼是快照測試。開始吧!

測試 props

在上一篇文章中,我們測試了通過一些 props 的結果。但是實際上,我們可以直接測試 props。讓我們回到上次的 ToDoList 組件,不過這次要用一個新的 Task 組件。

ToDoList.js
import React from 'react';  import Task from "../Task/Task";    const ToDoList = (props) => {    return (      <ul>        {          props.tasks.map(task =>            <Task key={task.id} id={task.id} name={task.taskName}/>          )        }      </ul>    )  };    export default ToDoList;    

我們將要測試 ToDoList 組件是否渲染 Task 組件,並將任務名稱傳遞給他們。

ToDoList.test.js
import React from 'react';  import { shallow } from 'enzyme';  import ToDoList from './ToDoList';    describe('ToDoList component', () => {    describe('when provided with an array of tasks', () => {      it('passes them to the Task components', () => {        const tasks = [          {            id: 0,            name: 'Wash the dishes'          },          {            id: 1,            name: 'Make the bed'          }        ];        const toDoListInstance = shallow(          <ToDoList tasks={tasks}/>        );        toDoListInstance.find('Task').forEach(taskInstance => {          const taskProps = taskInstance.props();          const matchingTask = tasks.find(task => task.id === taskProps.id);          expect(taskProps.name).toBe(matchingTask.name);        })      })    });  });    

通過測試,我們可以確保 Task 組件能夠從 ToDoList 接收正確的 props。

由於 toDoListInstance 和 taskInstance 均繼承自 ShallowWrapper,因此我們可以調用 props 函數。同樣,你可以檢查和更改狀態。有關可用函數的完整列表,請訪問文檔【https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md】。

但是如果我們想測試 Task 組件中 <li> 標記的實際內容怎麼辦?

toDoListInstance.find('Task').forEach(taskInstance => {    const taskProps = taskInstance.props();    const matchingTask = tasks.find(task => task.id === taskProps.id);    const listItem = taskInstance.first('li');    expect(listItem.text()).toBe(matchingTask.name);  })  

運行測試後你將會看到一個錯誤:

 FAIL  app/components/ToDoList/ToDoList.test.js    ● ToDoList component › when provided with array of tasks › passes them to the Task components        expect(received).toBe(expected) // Object.is equality        Expected: "Wash the dishes"      Received: "<Task />"          23 |         const matchingTask = tasks.find(task => task.id === taskProps.id);        24 |         const listItem = taskInstance.first('li');      > 25 |         expect(listItem.text()).toBe(matchingTask.name);           |                                 ^        26 |       })        27 |     })        28 |   });  

使用 mount 函數渲染

失敗了,因為我們在這裡用了「淺渲染」。在這種情況下子組件將根本不會被渲染。所以上面的測試失敗了,你需要了解「淺渲染」的局限性。

Mount 模擬了 DOM 的實現,而 Jest 默認使用 jsdom。你可以通過 testEnvironment 屬性【https://jestjs.io/docs/en/configuration.html#testenvironment-string】進行更改。

在早期版本的Enzyme中,在淺層渲染期間未調用生命周期方法。但是在 Enzyme 3.0 中發生了變化

const toDoListInstance = mount(    <ToDoList tasks={tasks}/>  );    

運行上面的程式碼將使整個 ToDoList 組件及其所有子組件渲染。前面失敗的測試現在將會通過。

由於 mount 函數可渲染更多內容並模仿實際的 DOM,所以測試將會花費更多時間。使用 mount 函數可能意味著你是在進行單元測試,而現在在進行集成測試。正是由於這個事實,使用 mount 函數能夠測試這些組件是否可以協同工作,而不僅僅是單獨的單元測試。

要弄清楚單元測試和集成測試的區別,請參見本教程第一部分。

在測試與 DOM 的交互或高階組件時,它也被證明是有用的。

要了解有關高階組件的更多資訊,請查看官方指南【https://reactjs.org/docs/higher-order-components.html】和 David Kopal 的文章【https://medium.freecodecamp.org/higher-order-components-the-ultimate-guide-b453a68bb851】

快照測試

在測試中使用快照是非常有用的。在測試期間,將渲染組件並創建其快照。它包含渲染組件的整個結構,應該與測試本身一起提交給存儲庫。再次運行快照測試時,新的快照將與舊的進行比較。如果它們不同,則測試將失敗。這將幫助你確保用戶介面不會被意外更改。

ToDoList.test.js
import React from 'react';  import { shallow } from 'enzyme';  import ToDoList from './ToDoList';    describe('ToDoList component', () => {    describe('when provided with an array of tasks', () => {      it('should render correctly', () => {        const tasks = [          {            id: 0,            name: 'Wash the dishes'          },          {            id: 1,            name: 'Make the bed'          }        ];        const toDoListInstance = shallow(          <ToDoList tasks={tasks}/>        );        expect(toDoListInstance).toMatchSnapshot();      });    });  });    

運行上面的程式碼將會創建一個名為 ToDoList.test.js.snap 的文件

ToDoList.test.js.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP    exports[`ToDoList component when provided with array of tasks should render correctly 1`] = `  <ul>    <Task      id={0}      key="0"      name="Wash the dishes"    />    <Task      id={1}      key="1"      name="Make the bed"    />  </ul>  `;  

要更新所有失敗的快照,你可以使用 `-u 標誌( --updateSnapshot的別名)運行 Jest。命令為 npm run test -- -u。

你還可以在 watch 模式下運行 Jest,這能夠允許你一個接一個地更新所有有衝突的快照。為了做到這一點,請運行 npm run test---watchAll,然後選擇 i 互動式地更新失敗的快照。官方 Jest 文檔【https://jestjs.io/docs/zh/snapshot-testing】中有一個很好的動畫演示了這個過程。

快照測試可以成為跟蹤組件更改的非常強大的工具。這樣可以防止你以意想不到的方式更改組件,從而迫使你查看所做的更改並接受或解決問題。因此它可用作監視程式碼的工具。

摘要

在本文中,我們介紹了對組件的 props 進行測試的過程,並了解了 mount 函數和 淺渲染 之間的區別。除此之外,我們還介紹了快照測試,它是跟蹤組件渲染方式變化的有用工具。在下一篇文章中,我們還將介紹組件的模擬交互,敬請關注!

原文:https://wanago.io/2018/09/10/javascript-testing-tutorial-part-three-testing-props-the-mount-function-and-snapshot-tests/

下面夾雜一些私貨:也許你和高薪之間只差這一張圖

2019年京程一燈課程體系上新,這是我們第一次將全部課程列表對外開放。

願你有個好前程,願你月薪30K。我們是認真的 !

在公眾號內回復「體系」查看高清大圖

Tags: