python - 如何在 Python 中对复制的 MagicMock 调用方法?

标签 python testing mocking python-unittest magicmock

我想测试一个函数是否在传递给它的对象上调用了 __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'

最佳答案

您需要在创建 mock 时提供 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()

关于python - 如何在 Python 中对复制的 MagicMock 调用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51735421/

相关文章:

python - NLTK 包和其他依赖项出现错误

testing - 没有检测的代码覆盖率

java - Mockito - InjectMocks 或如何在方法调用后获取新值

ruby-on-rails - 如何在 RSpec 中将测试与外部服务依赖项隔离

.net - 模拟 WCF 客户端代理的最佳方法

android - 如何正确使用Python对亚马逊网络服务进行自动化测试

python - python SyntaxError : unexpected EOF while parsing

python - 如何使 Django 与 MySQL 连接器/Python 一起工作?

database - Rails 4 自动测试模式不起作用

ruby-on-rails - 我如何在 Rails minitest 中使用 mock?