8

私はモックを初めて使用し、この関数の単体テストを作成しています:

# utils.py
import requests    

def some_function(user):
    payload = {'Email': user.email}
    url = 'http://api.example.com'
    response = requests.get(url, params=payload)      

    if response.status_code == 200:
       return response.json()
    else:
        return None

単体テストの一部としてMichael Foord の Mockライブラリを使用していますresponse.json()が、json 構造を返すために をモックするのが困難です。これが私の単体テストです:

# tests.py
from .utils import some_function

class UtilsTestCase(unittest.TestCase):
    def test_some_function(self):
        with patch('utils.requests') as mock_requests:
            mock_requests.get.return_value.status_code = 200
            mock_requests.get.return_value.content = '{"UserId":"123456"}'
            results = some_function(self.user)
            self.assertEqual(results['UserId'], '123456')

ドキュメントを読んだ後、運が悪かったため、さまざまなモック設定の組み合わせを数多く試しました。results単体テストを印刷すると、必要なjsonデータ構造ではなく、常に次のように表示されます。

<MagicMock name=u'requests.get().json().__getitem__().__getitem__()' id='30315152'>

私が間違っていることについて考えていますか?

4

3 に答える 3

2

私が好んで使用する、もう少し再利用可能な別のパターンは、単体テストのsetUpメソッドでパッチャーを開始することです。モック リクエストが予想されるパラメータで呼び出されたことを確認することも重要です。

class UtilsTestCase(TestCase):

    def setUp(self):
        self.user = Mock(id=123, email='foo@bar.com')

        patcher = patch('utils.requests.get')
        self.mock_response = Mock(status_code=200)
        self.mock_response.raise_for_status.return_value = None
        self.mock_response.json.return_value = {'UserId': self.user.id}
        self.mock_request = patcher.start()
        self.mock_request.return_value = self.mock_response

    def tearDown(self):
        self.mock_request.stop()

    def test_request(self):
        results = utils.some_function(self.user)

        self.assertEqual(results['UserId'], 123)

        self.mock_request.assert_called_once_with(
            'http://api.example.com'
            payload={'Email': self.user.email},
        )

    def test_bad_request(self):
        # override defaults and reassign
        self.mock_response.status_code = 500
        self.mock_request.return_value = self.mock_response
        results = utils.some_function(self.user)

        self.assertEqual(results, None)

        self.mock_request.assert_called_once_with(
            'http://api.example.com'
            payload={'Email': user.email},
        )
于 2015-07-23T18:23:28.467 に答える