91

私はmockPythonで使用するのにかなり苦労しています:

def method_under_test():
    r = requests.post("http://localhost/post")

    print r.ok # prints "<MagicMock name='post().ok' id='11111111'>"

    if r.ok:
       return StartResult()
    else:
       raise Exception()

class MethodUnderTestTest(TestCase):

    def test_method_under_test(self):
        with patch('requests.post') as patched_post:
            patched_post.return_value.ok = True

            result = method_under_test()

            self.assertEqual(type(result), StartResult,
                "Failed to return a StartResult.")

テストは実際には正しい値を返しますが、これr.okはモック オブジェクトであり、 ではありませんTruemockPython のライブラリで属性をどのようにモックしますか?

4

3 に答える 3

110

とを使用する必要がありreturn_valueますPropertyMock

with patch('requests.post') as patched_post:
    type(patched_post.return_value).ok = PropertyMock(return_value=True)

これは、 を呼び出すときに、その呼び出しの戻り値で、値を返すようにプロパティにrequests.posta を設定することを意味します。PropertyMockokTrue

于 2013-05-31T23:44:33.373 に答える
22

コンパクトで簡単な方法は、モック オブジェクトを作成する代わりに、new_callable patchの属性をpatch使用して強制的に使用することです。に渡された他の引数は、オブジェクトの作成に使用されます。PropertyMockMagicMockpatchPropertyMock

with patch('requests.post.ok', new_callable=PropertyMock, return_value=True) as mock_post:
    """Your test"""
于 2015-04-29T13:12:15.627 に答える
18

モック バージョン '1.0.1' では、質問に記載されているより単純な構文がサポートされ、そのまま機能します。

サンプルコードが更新されました (unittest の代わりに py.test が使用されます):

import mock
import requests


def method_under_test():
    r = requests.post("http://localhost/post")

    print r.ok

    if r.ok:
        return r.ok
    else:
        raise Exception()


def test_method_under_test():
    with mock.patch('requests.post') as patched_post:
        patched_post.return_value.ok = True

        result = method_under_test()
        assert result is True, "mock ok failed"

このコードを次のように実行します: (必ず pytest をインストールしてください)

$ py.test -s -v mock_attributes.py 
======= test session starts =======================
platform linux2 -- Python 2.7.10 -- py-1.4.30 -- pytest-2.7.2 -- /home/developer/miniconda/bin/python
rootdir: /home/developer/projects/learn/scripts/misc, inifile: 
plugins: httpbin, cov
collected 1 items 

mock_attributes.py::test_method_under_test True
PASSED

======= 1 passed in 0.03 seconds =================
于 2015-04-08T09:18:42.337 に答える