---
# System prepended metadata

title: Mock testing in Python 2.7
tags: [unittest, python, ' ']

---

# Mock testing in Python 2.7

最近工作上會維護一個滿舊的專案，是用 Python2.7 開發的，用的是 web2py framework

基於習慣，不管是 new feature / refactoring，我都會寫 uniit test

不過我對於 python 比較陌生，而且還是 v2，一開始很擔心找不到輔助資料，幸好網路上還是有一些基於 v2 的就資料，搭配自己 try and error，算是順利解決

---

new feature 是一個很簡單的 http request，需要依照 response 的 status code 和 content result 作一些不同的 action

看起來是一個很尋常的 case，我也是這麼想，就到 google 上找 ___mock http request in Python2.7___，[第一個](https://stackoverflow.com/questions/15753390/how-can-i-mock-requests-and-the-response) stackoverflow 就有很不錯的討論

其中[最高分](https://stackoverflow.com/questions/15753390/how-can-i-mock-requests-and-the-response#answer-28507806)的答案超級詳細的:

主要會需要 ``unittest`` ``requests`` ``mock`` 這三個 package

test class declaration
```python
class MyClassTestCase(unittest.TestCase):
    """
    test case...
    """
```

test case declaration:
```python
@mock.patch('requests.get', side_effect=mocked_requests_get)
def test_fetch(self, mock_get):
    """"
    test content
    """
```

``mock_get`` 是 mock object，若是 test case 比較複雜，例如需要測試傳入的參數，就可以利用它
另外就是 ``mock`` decoration，用來指定你想要 mock 的方法，以這邊為例，就是 `requests.get`，``side_effect`` 就是我們希望的 mock 內容，自行撰寫


---


## 範例

```python
import unittest
import mock
import requests
from requests.models import Response

CORRECT_URL = 'http://jsonplaceholder.typicode.com/todos'


def mock_get(*args, **kwargs):
    request_url = args[0]
    response = Response()
    if request_url == CORRECT_URL:
        response.status_code = 200
    else:
        response.status_code = 404
    return response


class TestClient(unittest.TestCase):
    @mock.patch('requests.get', side_effect=mock_get)
    def test_it_should_be_success(self, _):
        response = requests.get(CORRECT_URL)
        self.assertEqual(response.ok, True)
        self.assertEqual(response.status_code, 200)

    @mock.patch('requests.get', side_effect=mock_get)
    def test_it_should_be_failed_while_given_invalid_address(self, _):
        response = requests.get('invalid://url.will.be/failed')
        self.assertEqual(response.ok, False)
        self.assertEqual(response.status_code, 404)


if __name__ == '__main__':
    unittest.main()
```

###### tags: ``python`` ``unittest``


