2

我想测试一个函数是否__copy__在传递给它的对象上调用了该方法(使用给定的一组参数)。

由于创建对象需要数据库连接,我想我应该模拟它并将模拟传递给函数进行测试。

但是,它似乎__copy__正在返回一个不允许在其上调用任意方法的模拟(不确定是 Mock 还是 MagicMock)实例。由于我的代码在新对象上调用方法,因此它返回以下错误。

我怎样才能断言该__copy__方法已被调用并且仍然让函数的其余部分运行而没有错误?

FWIW,我尝试分配old_obj.__class__.return_value = MagicMock(),但似乎它没有返回我分配给它的内容(即我也分配... = 'foo'了但它仍然返回了一个模拟对象)。

例子:

class MyClass:
    def __init__(self, my_name):
        self.my_name = my_name

    def speak(self):
        print('My name is ' + self.my_name)


def my_func(old_obj, new_name):
    new_obj = old_obj.__class__(new_name)
    new_obj.speak()


def test_my_func():
    old_obj = MagicMock()
    old_obj.my_name = 'foo'

    my_func(old_obj, 'bar')

py.test 产生的错误:

self = <MagicMock spec='str' id='4490339552'>, name = 'speak'

    def __getattr__(self, name):
        if name in {'_mock_methods', '_mock_unsafe'}:
            raise AttributeError(name)
        elif self._mock_methods is not None:
            if name not in self._mock_methods or name in _all_magics:
>               raise AttributeError("Mock object has no attribute %r" % name)
E               AttributeError: Mock object has no attribute 'speak'
4

1 回答 1

0

spec创建模拟时需要提供参数,否则任何调用或属性都将返回一个mock.Mock()对象。

import unittest
from unittest import mock

class MyClass:
    def __init__(self, my_name):
        self.my_name = my_name
    def speak(self):
        print('My name is ' + self.my_name)

def my_func(old_obj, new_name):
    new_obj = old_obj.__class__(new_name)
    new_obj.speak()

def test_my_func():
    old_obj = mock.MagicMock(spec=MyClass)
    old_obj.my_name = 'foo'
    my_func(old_obj, 'bar')

if __name__ == '__main__':
    unittest.main()
于 2018-08-17T13:04:57.123 回答