天天看點

React 16 Jest ES6 Class Mocks(使用ES6文法類的模拟) 執行個體二React 16 Jest ES6 Class Mocks(使用ES6文法類的模拟) 執行個體二

轉載位址

React 16 Jest ES6 Class Mocks(使用ES6文法類的模拟) 執行個體二

項目初始化

git clone https://        github.com/durban89/webpack4-react16-reactrouter-demo.git                
cd webpack4-react16-reactrouter-demo
git fetch origin
git checkout v_1.0.30
npm install           

ES6 Class Mocks(使用ES6文法類的模拟)

Jest可用于模拟導入到要測試的檔案中的ES6文法的類。

ES6文法的類是具有一些文法糖的構造函數。是以,ES6文法的類的任何模拟都必須是函數或實際的ES6文法的類(這也是另一個函數)。

是以可以使用模拟函數來模拟它們。如下

ES6文法的類測試執行個體二,今天使用第二種方式 - 手動模拟(Manual mock)

ES6文法類的執行個體

這裡的執行個體我使用官方的例子,SoundPlayer類和SoundPlayerConsumer消費者類。下面部分檔案的内容參考上篇文章

React 16 Jest ES6 Class Mocks(使用ES6文法類的模拟)

src/lib/sound-player.js

export default class SoundPlayer {
  constructor() {
    this.name = 'Player1';
    this.fileName = '';
  }

  choicePlaySoundFile(fileName) {
    this.fileName = fileName;
  }

  playSoundFile() {
    console.log('播放的檔案是:', this.fileName);
  }
}           

src/lib/sound-player-consumer.js

import SoundPlayer from './sound-player';

export default class SoundPlayerConsumer {
  constructor() {
    this.soundPlayer = new SoundPlayer();
  }

  play() {
    const coolSoundFileName = 'song.mp3';
    this.soundPlayer.choicePlaySoundFile(coolSoundFileName);
    this.soundPlayer.playSoundFile();
  }
}           

通過在__mocks__檔案夾中建立一個模拟實作來建立手動模拟。

這個可以指定實作,并且可以通過測試檔案使用它。如下

src/lib/__mocks__/sound-player.js

export const mockChoicePlaySoundFile = jest.fn();
const mockPlaySoundFile = jest.fn();

const mock = jest.fn().mockImplementation(() => {
  const data = {
    choicePlaySoundFile: mockChoicePlaySoundFile,
    playSoundFile: mockPlaySoundFile,
  };

  return data;
});

export default mock;           

然後在測試用例中導入mock和mock方法,具體如下

import SoundPlayer, { mockChoicePlaySoundFile } from '../lib/sound-player';
import SoundPlayerConsumer from '../lib/sound-player-consumer';

jest.mock('../lib/sound-player'); // SoundPlayer 現在是一個模拟構造函數

beforeEach(() => {
  // 清除所有執行個體并調用構造函數和所有方法:
  SoundPlayer.mockClear();
  mockChoicePlaySoundFile.mockClear();
});

it('我們可以檢查SoundPlayerConsumer是否調用了類構造函數', () => {
  const soundPlayerConsumer = new SoundPlayerConsumer();
  expect(SoundPlayer).toHaveBeenCalledTimes(1);
});

it('我們可以檢查SoundPlayerConsumer是否在類執行個體上調用了一個方法', () => {
  const soundPlayerConsumer = new SoundPlayerConsumer();
  const coolSoundFileName = 'song.mp3';
  soundPlayerConsumer.play();
  expect(mockChoicePlaySoundFile).toHaveBeenCalledWith(coolSoundFileName);
});           

運作後得到的結果如下

 PASS  src/__tests__/jest_sound_player_2.test.js
   我們可以檢查SoundPlayerConsumer是否調用了類構造函數 (7ms)
   我們可以檢查SoundPlayerConsumer是否在類執行個體上調用了一個方法 (2ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.352s
Ran all test suites matching /src\/__tests__\/jest_sound_player_2.test.js/i.           

下次介紹第三、四種方法 - 使用子產品工廠參數調用jest.mock()(Calling jest.mock() with the module factory parameter)和使用mockImplementation()或mockImplementationOnce()替換mock(Replacing the mock using 

mockImplementation()

 or 

mockImplementationOnce()

)

實踐項目位址

git clone https://        github.com/durban89/webpack4-react16-reactrouter-demo.git               
git checkout v_1.0.31