如何模拟内置方法

时间:2016-02-25 15:09:37

标签: python mocking

我有一个对象,它定义了一个只有在首先实例化时才可访问的方法:

>>> import select
>>> select.poll().poll
<built-in method poll of select.poll object at 0x7fcf2a94bd80>
>>> select.poll.poll
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute 'poll'
>>> 

因此我嘲笑它(“民意调查”方法)。

>>> from unittest import mock
>>> import select
>>> with mock.patch('select.poll.poll') as m:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/unittest/mock.py", line 1197, in __enter__
    original, local = self.get_original()
  File "/usr/local/lib/python3.4/unittest/mock.py", line 1171, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <built-in function poll> does not have the attribute 'poll'

任何建议?

1 个答案:

答案 0 :(得分:1)

正如评论中所提到的,你最好嘲笑select.poll。您无需进一步了解该模块。您正在测试外部模块的行为,以便了解您的代码将如何对其做出反应。因此,你要记住这一点可以做到这一点:

import unittest
import select

from mock import mock, Mock


def my_method():
    select.poll()


class Testor(unittest.TestCase):
    @mock.patch('select.poll', return_value=Mock())
    def test_it(self, m_poll):    
        m_poll.side_effect = Exception

        with self.assertRaises(Exception):
            my_method()

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

因此,您模拟了补丁select.poll,然后当您调用poll()时,您将设置side_effect来引发异常。使用self.assertRaises检查在调用my_method时是否引发异常。

或者,如果您希望在poll内部模拟其他方法,可以执行以下操作:

import unittest
import select

from mock import mock, Mock


def my_method():
    s = select.poll()
    s.poll()


class Testor(unittest.TestCase):
    @mock.patch('select.poll', return_value=Mock())
    def test_it(self, m_poll):
        m_poll.return_value.poll.side_effect = Exception
        with self.assertRaises(Exception):
            my_method()

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

m_poll.return_value的返回值,获取side_effect的{​​{1}}以返回poll