模拟补丁不适用于__init__.py中的类

Dav*_*d S 12 python unit-testing mocking twilio

我正在尝试使用补丁从方法中返回一个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()
Run Code Online (Sandbox Code Playgroud)

上面的代码对我来说很好.但是,当我将相同的模式应用于我正在尝试测试的实际代码时,真实对象(不是模拟对象)将在被测试的方法中返回.我看不出任何差异.唯一不同的是,真正的类是在init .py文件中定义的.我不确定这是否有所作为?以前见过这个吗?

注意:实际的lib是twilio 3.3.5,我使用的是Python 2.6.5和Django 1.3.1以及Mock 0.7.2

Dav*_*d S 11

我想到了.它与__init__.py文件无关.这是(像往常一样)我的错!:)

对于每个试图在未来使用Mock和补丁与Twilio和SMS的人来说,这里是解决方案:

我正在模拟类twilio.rest.TwilioRestClient但是,事情被链接在一起,我需要在内部类调用SmsMessage上调用补丁.所以,对于我的单元测试,这很好用:

@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)
Run Code Online (Sandbox Code Playgroud)

注意:send_sms实际上是我试图测试的功能.我只是想确保它按预期调用twilio并提供default_from_number.default_from_number值在设置文件中定义,对于此示例并不重要.