Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python模拟中的模拟属性?_Python_Unit Testing_Testing_Mocking_Python Mock - Fatal编程技术网

Python模拟中的模拟属性?

Python模拟中的模拟属性?,python,unit-testing,testing,mocking,python-mock,Python,Unit Testing,Testing,Mocking,Python Mock,我在Python中使用mock时遇到了相当大的困难: 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(

我在Python中使用
mock
时遇到了相当大的困难:

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.")
def method_under_test():
r=请求。post(“http://localhost/post")
打印r.ok#打印“”
如果r.ok:
返回StartResult()
其他:
引发异常()
类MethodUnderTestTest(TestCase):
def测试下的def测试方法(自):
将补丁('requests.post')作为补丁发布:
已修补的\u post.return\u value.ok=True
结果=试验()下的方法
self.assertEqual(类型(结果)、StartResult、,
“未能返回StartResult。”)
测试实际上返回正确的值,但是
r.ok
是模拟对象,而不是
True
。如何在Python的
mock
库中模拟属性?

您需要使用和:


这意味着:在调用
请求时。post
,在该调用的返回值上,为属性
ok
设置
PropertyMock
,以返回值
True

使用模拟版本“1.0.1”,问题中提到的更简单语法将得到支持并按原样工作

示例代码更新(使用py.test代替unittest):

运行以下代码:(确保安装了pytest)


一种紧凑而简单的方法是使用
new\u callable
patch
的属性强制
patch
使用
PropertyMock
而不是
MagicMock
来创建模拟对象。传递给
patch
的其他参数将用于创建
PropertyMock
对象

with patch('requests.post.ok', new_callable=PropertyMock, return_value=True) as mock_post:
    """Your test"""

如果我在测试下的
方法中打印
r.ok
的值,我看到
,而不是
True
@TKKocheran:我已经更新了我的答案。您还需要使用
PropertyMock
。为什么不简单地使用
patched\u post.return\u value=mock.mock(ok=True)
?@lumbric,因为您可以使用
PropertyMock
来声明它与任何其他
mock
对象一样被访问。仅仅给属性赋值是做不到的。这并不能回答这个问题。若要评论或要求作者澄清,请在其帖子下方留下评论-您可以随时对自己的帖子发表评论,一旦您有足够的评论,您就可以发表评论。仅供参考
请求。post.ok
是一个属性,而不是一个属性。如果您尝试使用简单对象,其中
ok
是一个简单属性,则问题中提到的语法适用于
请求。post.ok
对象否:它将引发
AttributeError
@philant感谢您的反馈,正如示例所证明的,这是问题的最新答案,语法恰好简单得多。@Micheled'Amico感谢您的反馈,我试过了,请看一看;-)
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"
$ 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 =================
with patch('requests.post.ok', new_callable=PropertyMock, return_value=True) as mock_post:
    """Your test"""