Mock patch 在 __init__.py 中对类无效
我正在尝试使用补丁(patch)来在一个方法中返回一个模拟对象(Mock)。基本结构如下:
MyCode.py
class MyClass:
def __init__(self, first_name, last_name):
self.first = first_name
self.last = last_name
def get_greeting(self):
return 'Hello {f} {l}'.format(f=self.first, l=self.last)
def get_new_greeting(first_name, last_name):
obj = MyClass(first_name, last_name)
return obj.get_greeting()
my_code_test.py
import unittest
from mock import Mock, patch
import my_code
class TestMyCode(unittest.TestCase):
def setUp(self):
pass
@patch('my_code.MyClass')
def test_get_greeting(self, MockClass):
instance = MockClass.return_value
mock_greeting = 'Hello Me'
instance.get_greeting.return_value = mock_greeting
greeting = my_code.get_new_greeting('john', 'doe')
self.assertEqual(greeting, mock_greeting)
if __name__ == '__main__':
unittest.main()
上面的代码对我来说运行得很好。不过,当我把同样的方式应用到我想要测试的真实代码时,测试的方法中返回的却是实际对象(而不是模拟对象)。我看不出有什么不同。唯一有点不同的是,真实的类是在一个init.py文件中定义的。我不确定这是否会有影响?有没有人遇到过这种情况?
注意:实际使用的库是twilio 3.3.5,我使用的是Python 2.6.5、Django 1.3.1和Mock 0.7.2。
1 个回答
11
我搞明白了。这和 __init__.py
文件没有关系。问题完全是我自己的错! :)
为了帮助将来有需要使用 Mock 和 patch 结合 Twilio 和短信的人,这里有个解决方案:
我在模拟类 twilio.rest.TwilioRestClient,但事情是有层次关系的,我需要在内部类 SmsMessage 上调用 patch。所以,在我的单元测试中,这样做效果很好:
@patch('twilio.rest.resources.SmsMessages')
def test_send_msg_valid_args(self, MockClass):
instance = MockClass.return_value
instance.create.return_value = None
to_number = '+15555555555'
msg = 'Hello world'
send_sms(to_number, msg)
instance.create.assert_called_once_with(to=to_number, body=msg, from_=default_from_number)
注意:send_sms 实际上是我想测试的函数。我只是想确保它按预期调用了 Twilio,并提供了 default_from_number。default_from_number 的值是在设置文件中定义的,对于这个例子来说并不是特别重要。