python - HTTPrettyでhttp通信を奪う

Mockモジュールでもいいっちゃいいんだけど
偶然見つけたので試してみた。

GETを奪う

HTTPretty.register_uriで奪いたいURLと期待するレスポンスを書くだけでOK。

# encoding:utf-8
import unittest
from httpretty import HTTPretty, httprettified
from httpretty import 
from urllib  import urlencode
from urllib2 import urlopen

import json

class TestFakeHTTP(unittest.TestCase):
    @httprettified
    def test_get(self):
        url = "http://fakedayooon.jp/"
        HTTPretty.register_uri(HTTPretty.GET,
                               url,
                               body='{"title": "hahaha!!!"}',
                               content_type="application/json")
        res = urlopen(url)
        content = json.loads(res.read())
        # contentが置き換わってる
        self.assertDictEqual(content, {"title": "hahaha!!!"})

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

最後にリクエストした内容もチェックできる

HTTPretty.last_requestというメソッドを使うと
最後にリクエストした内容を取得出来ます。
きちんとパラメータを渡しているかどうかもテスト出来ますね。

    @httprettified
    def test_post(self):
        url = "http://fakedayooon.jp/apps/test"
        HTTPretty.register_uri(HTTPretty.POST,
                               url,
                               body='{"title": "buchoooo????"}',
                               content_type="application/json")
        params = urlencode({
          'id'    : 'hogem',
        })
        res = urlopen(url, params)
        content = json.loads(res.read())
        assert res.code == 200
        # ヘッダーとかパラメータとかチェック出来る
        assert HTTPretty.last_request.headers['content-type'] == 'application/x-www-form-urlencoded'
        assert HTTPretty.last_request.body == 'id=hogem'

レスポンスの内容を複数指定できる

responsesに複数入力することにより
レスポンスさせる内容を変化させたりもできる。

    @httprettified
    def test_rotate(self):
        url = "http://fakedayooon.jp/apps/rotate?key=onara"
        HTTPretty.register_uri(HTTPretty.GET,
                               url,
                               responses=[
                                   HTTPretty.Response(body="uriiiiiii",          status=201),
                                   HTTPretty.Response(body='mudamudamudamudaaa', status=202),
                               ])
        # 1回目
        res = urlopen(url)
        content = res.read()
        assert res.code == 201
        assert content  == 'uriiiiiii'
        self.assertDictEqual(HTTPretty.last_request.querystring, {'key':['onara']})

        # 2回目
        res = urlopen(url)
        content = res.read()
        assert res.code == 202
        assert content  == 'mudamudamudamudaaa'

        # 3回目以降は最後のと同じ
        res = urlopen(url)
        content = res.read()
        assert res.code == 202
        assert content  == 'mudamudamudamudaaa'

URLマッチを使う

    @httprettified
    def test_match(self):
        url = "http://fakedayooon.jp/apps/alpaca"
        HTTPretty.register_uri(
            HTTPretty.GET,
            re.compile("fakedayooon.jp/apps/(\w+)"),
            body="ryama fukafuka",
        )

        res = urlopen(url)
        content = res.read()
        assert content  == 'ryama fukafuka'

動的にレスポンスを返す

    @httprettified
    def test_dynamic(self):

        def request_callback(method, uri, headers):
            return "method is {}".format(method)

        url = "https://api.yahoo.com/test?atama=hage"
        HTTPretty.register_uri(
            HTTPretty.GET,
            url,
            body=request_callback,
        )
        res = urlopen(url)
        content = res.read()


便利!