让 Pytest、Relative Import 和 Patch.Object 合作 [英] Getting Pytest, Relative Import, and Patch.Object to Cooperate

查看:49
本文介绍了让 Pytest、Relative Import 和 Patch.Object 合作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在获得 pytest、相对导入和补丁合作方面很忙.

I'm having a hell of a time getting pytest, relative import, and patch to cooperate.

我有以下几点:

from .. import cleanup

class CleanupTest(unittest.TestCase):

    @patch.object(cleanup, 'get_s3_url_components', MagicMock())
    @patch.object(cleanup, 'get_db_session', MagicMock(return_value={'bucket', 'key'}))
    @patch('time.time')
    def test_cleanup(self, mock_time, mock_session, mock_components):
        ...

我尝试了一些变体.

  1. 当前显示的一个.Pytest 返回TypeError: test_cleanup() 需要 4 个参数(给定 2 个)".它无法识别 patch.objects,即使我很确定我根据 https://docs.python.org/3/library/unittest.mock-examples.html
  2. 将 patch.objects 更改为简单的补丁会导致它们抛出no module named cleanup".我不知道如何在相对导入中使用补丁.

我使用的是 Python 2.7,以防万一.

I'm using Python 2.7 in case that's relevant.

推荐答案

这实际上与 pytest 没有任何关系,只是 mock 的行为装饰器

this actually doesn't have anything to do with pytest and is merely the behaviour of the mock decorators

来自文档

如果 patch() 用作装饰器并且省略 new,则创建的模拟将作为额外参数传入装饰函数

If patch() is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function

也就是说,因为您传递的是替换对象,所以不会发生签名突变

that is, because you're passing a replacement object the signature-mutation doesn't occur

例如:

from unittest import mock

class x:
    def y(self):
        return 'q'

@mock.patch.object(x, 'y', mock.Mock(return_value='z'))
def t(x): ...


t()  # TypeError: t() missing 1 required positional argument: 'x'

幸运的是,如果您正在生成一个 mock 对象,您很少需要实际传入 new 参数并且可以使用关键字 options

Fortunately, if you're producing a mock object, you rarely need to actually pass in the new argument and can use the keyword options

对于您的特定示例,这应该可以正常工作:

For your particular example this should work fine:

    @patch.object(cleanup, 'get_s3_url_components')
    @patch.object(cleanup, 'get_db_session', return_value={'bucket', 'key'})
    @patch('time.time')
    def test_cleanup(self, mock_time, mock_session, mock_components): ...

如果你绝对需要它们是 MagicMocks,你可以使用 new_callable=MagicMock 关键字参数

If you absolutely need them to be MagicMocks, you can use the new_callable=MagicMock keyword argument

这篇关于让 Pytest、Relative Import 和 Patch.Object 合作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆