iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Modern Web

我不會測試,所以寫Jest與React Testing Library系列 第 3

Day 3 我要開始Mock了

Mock

What's mock?

先想像一個畫面,當我們要隔離我們的元件時,一個component裡面有諸多事件(event),不管是點選抓資料或者是useEffect去撈資料,但在測試階段可能會外部元件進行交互e.g.call api.

這些行為的產生會為產生的結果產生不確定性,所以我們希望在做單元測試時,可以元件保持獨立性(),各個元件之間不會互相影響,那如何做到? 那我們就來寫個範例吧

export const GETv1CommonMsg = () => Promise.resolve('fetch successful');

再來

const [message, setMessage] = useState('fetch failure');

useEffect(() => {
  const getMsg = async () => {
    const res = await GETv1CommonMsg();
    
    if (res) {
      setStatus(res);
    }
  }

  getMsg();
}, []);

有關於react hooks相關簡介,會在後面章節簡介.


這裡暫停一下,看到這一幕,大家腦袋想一下,我們的message怎樣變化.

很多人一定想,message會從fetch failure → fetch successful,答案是你沒猜錯這就是正確答案,但這時候您們可以想一下,啊 我是不是依賴到GETv1CommonMsg這個function了,因為我現在這邊return 回來的值是hard code,假如不同會產生什麼問題?

  1. 回傳值會因為時間或者是各種因素產生不同的結果,導致測試失敗
  2. 在測試時,真實的模擬打API造成無謂的流量浪費,如果測試案例一大,流量你知道的

這時候我們就把這個api mock起來

import { render, screen } from '@testing-library/react';
import App from './App';
import * as apis from './utils/api';

const mock = jest.spyOn(apis, 'GETv1ConsumerList');

test('should show success message', async () => {
  mock.mockImplementation(() => Promise.resolve('good!'));
  render(<App />);
  expect(mock).toHaveBeenCalledTimes(1)
})

toHaveBeenCalledTimes是testing-library/react的api 稍後會介紹


上一篇
Day 2 我要開始學了
下一篇
Day 4 jest的生命週期
系列文
我不會測試,所以寫Jest與React Testing Library30

尚未有邦友留言

立即登入留言