So können Sie es machen (Sie können diese Datei wie sie ist ausführen) :
import requests
import unittest
from unittest import mock
# Dies ist die Klasse, die wir testen möchten
class MyGreatClass:
def fetch_json(self, url):
response = requests.get(url)
return response.json()
# Diese Methode wird vom Mock verwendet, um requests.get zu ersetzen
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)
# Unsere Testfall-Klasse
class MyGreatClassTestCase(unittest.TestCase):
# Wir patchen 'requests.get' mit unserer eigenen Methode. Das Mock-Objekt wird an unsere Testfall-Methode übergeben.
@mock.patch('requests.get', side_effect=mocked_requests_get)
def test_fetch(self, mock_get):
# Assert-Anrufe von requests.get
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)
# Wir können sogar überprüfen, ob unsere Mock-Methode mit den richtigen Parametern aufgerufen wurde
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()
Wichtiger Hinweis: Wenn Ihre MyGreatClass
-Klasse in einem anderen Paket lebt, sagen wir in my.great.package
, müssen Sie my.great.package.requests.get
statt nur 'requests.get' mocken. In diesem Fall würde Ihr Testfall so aussehen:
import unittest
from unittest import mock
from my.great.package import MyGreatClass
# Diese Methode wird vom Mock verwendet, um requests.get zu ersetzen
def mocked_requests_get(*args, **kwargs):
# Wie oben
class MyGreatClassTestCase(unittest.TestCase):
# Jetzt müssen wir 'my.great.package.requests.get' patchen
@mock.patch('my.great.package.requests.get', side_effect=mocked_requests_get)
def test_fetch(self, mock_get):
# Wie oben
if __name__ == '__main__':
unittest.main()
Viel Spaß!