リクエストとレスポンスをモックするにはどうすればいいですか? 質問する

リクエストとレスポンスをモックするにはどうすればいいですか? 質問する

使用しようとしていますPythons モックパッケージPython モジュールをモックしますrequests。以下のシナリオで動作させるための基本的な呼び出しは何ですか?

私のviews.pyには、毎回異なる応答でさまざまなrequests.get()呼び出しを行う関数があります。

def myview(request):
  res1 = requests.get('aurl')
  res2 = request.get('burl')
  res3 = request.get('curl')

私のテストクラスでは、このようなことをしたいのですが、正確なメソッド呼び出しがわかりません

ステップ1:

# Mock the requests module
# when mockedRequests.get('aurl') is called then return 'a response'
# when mockedRequests.get('burl') is called then return 'b response'
# when mockedRequests.get('curl') is called then return 'c response'

ステップ2:

私の意見を呼ぶ

ステップ3:

応答に「a 応答」、「b 応答」、「c 応答」が含まれていることを確認します

ステップ 1 (リクエスト モジュールのモック) を完了するにはどうすればよいですか?

ベストアンサー1

実行方法は次のとおりです (このファイルをそのまま実行できます)。

import requests
import unittest
from unittest import mock

# This is the class we want to test
class MyGreatClass:
    def fetch_json(self, url):
        response = requests.get(url)
        return response.json()

# This method will be used by the mock to replace requests.get
def mocked_requests_get(*args, **kwargs):
    class MockResponse:
        def __init__(self, json_data, status_code):
            self.json_data = json_data
            self.status_code = status_code

        def json(self):
            return self.json_data

    if args[0] == 'http://someurl.com/test.json':
        return MockResponse({"key1": "value1"}, 200)
    elif args[0] == 'http://someotherurl.com/anothertest.json':
        return MockResponse({"key2": "value2"}, 200)

    return MockResponse(None, 404)

# Our test case class
class MyGreatClassTestCase(unittest.TestCase):

    # We patch 'requests.get' with our own method. The mock object is passed in to our test case method.
    @mock.patch('requests.get', side_effect=mocked_requests_get)
    def test_fetch(self, mock_get):
        # Assert requests.get calls
        mgc = MyGreatClass()
        json_data = mgc.fetch_json('http://someurl.com/test.json')
        self.assertEqual(json_data, {"key1": "value1"})
        json_data = mgc.fetch_json('http://someotherurl.com/anothertest.json')
        self.assertEqual(json_data, {"key2": "value2"})
        json_data = mgc.fetch_json('http://nonexistenturl.com/cantfindme.json')
        self.assertIsNone(json_data)

        # We can even assert that our mocked method was called with the right parameters
        self.assertIn(mock.call('http://someurl.com/test.json'), mock_get.call_args_list)
        self.assertIn(mock.call('http://someotherurl.com/anothertest.json'), mock_get.call_args_list)

        self.assertEqual(len(mock_get.call_args_list), 3)

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

重要な注意:MyGreatClassクラスが別のパッケージ (たとえば ) に存在する場合は、単に 'request.get' ではなく、my.great.packageモックを使用する必要があります。その場合、テスト ケースは次のようになります。my.great.package.requests.get

import unittest
from unittest import mock
from my.great.package import MyGreatClass

# This method will be used by the mock to replace requests.get
def mocked_requests_get(*args, **kwargs):
    # Same as above


class MyGreatClassTestCase(unittest.TestCase):

    # Now we must patch 'my.great.package.requests.get'
    @mock.patch('my.great.package.requests.get', side_effect=mocked_requests_get)
    def test_fetch(self, mock_get):
        # Same as above

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

楽しむ!

おすすめ記事