1. 程式人生 > >React 16 Jest使用ES模組匯入和模擬JSDOM中未實現的方法

React 16 Jest使用ES模組匯入和模擬JSDOM中未實現的方法

轉載

專案初始化

git clone https:
cd webpack4-react16-reactrouter-demo
git fetch origin
git checkout v_1.0.28
npm install

Using with ES module imports(使用ES模組匯入)

我們在使用ES模組時做匯入的時候,會習慣性的將匯入的語句放在測試檔案的頂部。但是在使用Jest的時候,需要指示Jest在模組使用之前進行模擬操作。
正是由於這個原因,Jest會自動將jest.mock的呼叫提升到模組的頂部(在任何匯入之前)

Mocking methods which are not implemented in JSDOM(模擬JSDOM中未實現的方法)

如果某些程式碼在使用JSDOM(Jest使用的DOM實現)尚未實現的方法的時候,這個情況在測試時是比較麻煩的。比如我們呼叫window.matchMedia()的時候,Jest返回TypeError:window.matchMedia不是函式,並且沒有正確執行測試。
在這種情況下,在測試檔案中模擬matchMedia就可以解決類似的問題:如下

window.matchMedia = jest.fn().mockImplementation(query => {
  return {
    matches: false,
    media: query,
    onchange: null
, addListener: jest.fn(), removeListener: jest.fn(), }; });

如果window.matchMedia()用於在測試中呼叫的函式(或方法),則此方法有效。
如果window.matchMedia()直接在測試檔案中執行,則Jest報告相同的錯誤。
在這種情況下,解決方案是將手動模擬移動到單獨的檔案中,並在測試檔案之前將其包含在測試中:例項如下

import './matchMedia.mock'; // Must be imported before the tested file
import { myMethod } from './file-to-test'
; describe('myMethod()', () => { // Test the method here... });


這裡官方就是簡單的介紹了下,導致有些學者可能還是雲裡霧裡的,下面簡單的寫個例項
建立檔案
src/lib/matchMedia.mock.js

window.matchMedia = jest.fn().mockImplementation((query) => {
  const obj = {
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
  };

  return obj;
});

src/lib/useMatchMedia.js

const useMatchMedia = () => {
  const res = window.matchMedia;
  return res;
};

module.exports = {
  useMatchMedia,
};


建立完檔案後,新增測試檔案
src/__tests__/useMatchMedia.test.js
第一次我們不呼叫src/lib/matchMedia.mock.js這個檔案

// import '../lib/matchMedia.mock';
import { useMatchMedia } from '../lib/useMatchMedia';

describe('useMatchMedia()', () => {
  it('useMatchMedia() 被呼叫', () => {
    const res = useMatchMedia();
    expect(res).toBeUndefined();
    // expect(res).toBeDefined();
  });
});


第二次我們呼叫src/lib/matchMedia.mock.js這個檔案

import '../lib/matchMedia.mock';
import { useMatchMedia } from '../lib/useMatchMedia';

describe('useMatchMedia()', () => {
  it('useMatchMedia() 被呼叫', () => {
    const res = useMatchMedia();
    expect(res).toBeDefined();
  });
});


從上面的例子大概就能理解基本上官方的意思了,具體如何使用,這個可以自己有發揮。

如果國內的使用者還是不知道如何流暢的執行jest的話建議翻翻我前面的文章。
專案實踐地址