test API with mock function

此篇有使用 isomorphic-fetch Library

1.fetch api

新建 root/app/api/users.js 使用此class 將call我們要的API寫成一個function

class Users {
  static all() {
    return fetch('https://facebook.github.io/react-native/movies.json')
    .then((response) => {
      if(response) {
          return response.json();
      }
    });
  }
}

export default Users;

2.call fetch

在 root/app/Home.js 內 call 步驟1所寫的function

import React, { Component } from 'react';
import { StyleSheet, View, TextInput } from 'react-native';
import Users from './api/users';

export default class Home extends Component {

  componentDidMount() {
    Users.all().then((data)=> {
      console.warn("check api data", data);
    });
  }

  render() {
    return (
      <View style={styles.wrapper}>
        <TextInput
          testID={'username'}
          style={{backgroundColor: 'gray', marginBottom: 35}} 
          placeholder={'Enter User Name'} />
        
        <TextInput
          testID={'password'}
          style={{backgroundColor: 'gray'}} 
          placeholder={'Enter Password'} />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  wrapper: {
    flex:1, 
    justifyContent: 'center'
  },
})

執行App後,可看見call API要到的內容

3.撰寫測試的 test case

在此步驟先撰寫測試的 test case,確認是否OK 新建 root/__tests__/HomeMockApi-test.js

import Users from '../app/api/users';

it('Api test', async function() {
  global.fetch = jest.fn().mockImplementation(()=>{
    var p = new Promise((resolve, reject) => {
      resolve({
          json:function() {
            return {Id:1}
          }
      })
    })
    return p;
  })

  const response = await Users.all();
//   console.log(response);
  expect(response.Id).toBe(1);
})

下圖說明Code

執行此test case ,成功

此時的 Users.all() 並非真的跑去call fb那串API,因為 global.fetch... 所以被判定使用模擬函數(mock function )

4.撰寫實際例子的 test case

步驟三成功後,就開始實際的例子吧!

​ 1) 將測試的mock function註解掉後執行test,會得到 fetch is not defined 的錯誤,如下圖。

fetch is not defined的原因: 在測試區域(test area)內,我們無法通過 test 偵測它到底是什麼東西,所以我們使用 isomorphic-fetch

​ 2) 安裝 isomorphic-fetch

$ npm install --save isomorphic-fetch es6-promise
$ npm install

3) 在 HomeMockApi-test.js內import isomorphic-fetch 執行test case,結果是失敗,但可以看到成功印出從API內獲取的內容,如下圖

import Users from '../app/api/users';
import 'isomorphic-fetch';

it('Api test', async function() {
  const response = await Users.all();
  console.log(response);
  expect(response.Id).toBe(1);
})

5) 修改expect 直接拿此 fb API 內的 movies 中隨便一比的 title 來測試,code 如下

import Users from '../app/api/users';
import 'isomorphic-fetch';

it('Api test', async function() {
  const response = await Users.all();
//   console.log(response);
  expect(response.movies[3].title).toEqual('Inception');
})

執行後成功,如下圖 (API內容可透過網頁開啟URL查看)

參考

Last updated