简体   繁体   English

如何模拟内置方法

[英]How to mock a builtin method

I have an object which defines a method which is accessible only if it's instantiated first: 我有一个对象,该对象定义仅在首先实例化时才可访问的方法:

>>> 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'
>>> 

As such I am having troubles mocking it (the "poll" method). 因此,我在嘲笑它时遇到了麻烦(“轮询”方法)。

>>> 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'

Any recommendation? 有什么建议吗?

As mentioned in the comments, you are better off mocking select.poll . 如评论中所述,最好还是嘲笑select.poll You don't need to go further in to that module. 您无需进一步研究该模块。 You are testing the behaviour of an external module raising something to know how your code will react to it. 您正在测试外部模块的行为,该行为引发了一些事情,以了解您的代码将如何对此做出反应。 Therefore, what you can do with keeping that in mind is this: 因此,请记住以下几点:

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()

So, you mock patch select.poll , and then when you call poll() you will have a side_effect set to raise an exception. 因此,您可以模拟补丁select.poll ,然后在调用poll()设置了side_effect来引发异常。 With the self.assertRaises to check if an exception does get raised when you call my_method . 使用self.assertRaises来检查在调用my_method时是否引发了异常。

Alternatively, if you are looking to really mock an additional method inside poll, you can do something like this: 另外,如果您想在模拟内部真正模拟其他方法,则可以执行以下操作:

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()

From the return value of m_poll.return_value , get the side_effect of poll to return your Exception . m_poll.return_value的返回值中,获取pollside_effect以返回您的Exception

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM