> For the complete documentation index, see [llms.txt](https://twins-bamboo.gitbook.io/react-native-note/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://twins-bamboo.gitbook.io/react-native-note/test/jest/test-api-with-mock-function.md).

# test API with mock function

{% hint style="info" %}
此篇要call的API為 <https://facebook.github.io/react-native/movies.json>
{% endhint %}

### 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要到的內容

![](/files/-LHbIU7RLlfMZku_3EtD)

### 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

![](/files/-LHbMvAsV2_CcIMUsQGi)

#### 執行此test case ，成功

![](/files/-LHbNGOmANuiRcxfdzaF)

{% hint style="warning" %}
此時的 Users.all() 並非真的跑去call fb那串API，因為 global.fetch... 所以被判定使用模擬函數(mock  function )
{% endhint %}

###

### 4.撰寫實際例子的 test case

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

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

![](/files/-LHbtfo4OXRQRGi6Mbad)

{% hint style="warning" %}
fetch is not defined的原因:\
在測試區域(test area)內，我們無法通過 test 偵測它到底是什麼東西，所以我們使用 **isomorphic-fetch** &#x20;
{% endhint %}

&#x20;​ 2) 安裝 isomorphic-fetch

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

&#x20; 3\) 在 HomeMockApi-test.js內import isomorphic-fetch\
&#x20;      執行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);
})
```

![](/files/-LHc8AV7v5--pRsMYe0F)

&#x20; 5\) 修改expect\
&#x20;      直接拿此 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查看)

![](/files/-LHcABJJvJJWXgWFK09R)

{% hint style="info" %}
[isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) Library
{% endhint %}

### 參考

* [React-Native Test with jest #4 | test Api with mock function](https://www.youtube.com/watch?v=qpKaSdBX9QU\&index=4\&list=PL8p2I9GklV46mGMh5X1pzuDWidnRrlHyp)
* [React-Native Test with jest #5 | test Api with simple example](https://www.youtube.com/watch?v=b4FKuH07Hc4\&list=PL8p2I9GklV46mGMh5X1pzuDWidnRrlHyp\&index=6)
