Mock补丁在__init__.py中无法使用类。

13

我正在尝试使用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
你可能需要发布那些出现问题的代码,而不是正常工作的代码。 - Daniel Roseman
@DanielRoseman非常有道理。我使用这种方法的原因是我认为很少有人会有twilio包并且可能不想安装它(虽然如果您使用virtualenv,这并不是什么大问题),而且我想展示我理解我需要做什么的基本原则。谢谢您的回复。 - David S
1个回答

11

我弄清楚了,这与__init__.py文件无关。像往常一样,是我的错! :)

对于任何未来想要使用Mock和patch来发送Twilio短信的人,这里是解决方案:

我Mock了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的值在设置文件中定义,对于这个示例并不重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接