标签: python-mock

如何在pytest中全局修补?

我的代码使用pytest相当多.示例代码结构如下所示.整个代码库是python-2.7

core/__init__.py
core/utils.py

#feature

core/feature/__init__.py
core/feature/service.py

#tests
core/feature/tests/__init__.py
core/feature/tests/test1.py
core/feature/tests/test2.py
core/feature/tests/test3.py
core/feature/tests/test4.py
core/feature/tests/test10.py
Run Code Online (Sandbox Code Playgroud)

service.py看起来是这样的:

from modules import stuff
from core.utils import Utility


class FeatureManager:
    # lots of other methods
    def execute(self, *args, **kwargs):
        self._execute_step1(*args, **kwargs)
        # some more code
        self._execute_step2(*args, **kwargs)
        utility = Utility()
        utility.doThings(args[0], kwargs['variable'])
Run Code Online (Sandbox Code Playgroud)

所有测试feature/tests/*最终都使用了core.feature.service.FeatureManager.execute功能.但是utility.doThings(),在运行测试时,我没有必要运行.我需要它在生产应用程序运行时发生,但我不希望它在测试运行时发生.

我可以做我这样的事 core/feature/tests/test1.py

from mock import patch

class Test1:
   def test_1():
       with patch('core.feature.service.Utility') as MockedUtils:
           exectute_test_case_1()
Run Code Online (Sandbox Code Playgroud)

这会奏效.但是我Utility刚刚添加到代码库中,我有超过300个测试用例.我不想进入每个测试用例并写下这个with语句.

我可以写一个conftest.py设置一个os级环境变量,根据该环境变量core.feature.service.FeatureManager.execute …

python tdd pytest python-mock

7
推荐指数
2
解决办法
3290
查看次数

在 Python 中使用“@patch.object”和“with patch.object”有什么区别?

在为我的应用程序编写单元测试时,我一直在使用@mock.patch@patch.object装饰器。但是现在,对于使用装饰器时的某些单元测试,我收到错误“ TypeError: staticmethod object is not an iterator ”。

但是使用相同的代码,如果我使用mock.patch.objector mock.patch.object,一切正常。

例如,在我的测试类中,我有这个方法:

@staticmethod
def my_mock():
   ...do something
Run Code Online (Sandbox Code Playgroud)

当我尝试以下单元测试时

@mock.patch('mypackage.mymodule.my_method', side_effect=my_mock)
def test_something(self, my_method_mocked):
    ...test something
Run Code Online (Sandbox Code Playgroud)

我收到了“ TypeError: staticmethod object is not an iterator ”之前所述的错误消息。

但是当我尝试这种方式时

def test_something(self):
    with patch.object(mymodule, "my_method") as mocked_method:
        mocked_method.side_effect = self.my_mock
        ...test something
Run Code Online (Sandbox Code Playgroud)

然后一切正常。

我已经阅读了有关模拟和单元测试的 Python 文档,但找不到对此行为的任何解释。

使用装饰器模式使用模式有什么区别?我在哪里可以找到更多关于这方面的信息?

为了更清楚,这是我的代码结构:

class TestClass(unittest.TestCase):

    @staticmethod
    def my_mock():
    ...mock
        return service

    # doesn't work
    @mock.patch('mypackage.mymodule.my_method', side_effect=my_mock)
    def test_something(self, my_method_mocked): …
Run Code Online (Sandbox Code Playgroud)

python unit-testing python-2.7 python-mock python-unittest

7
推荐指数
1
解决办法
6954
查看次数

模拟不适用于模块功能

我编写了send_formatted_email格式化电子邮件主题和消息的send_email函数,然后在单独的模块中调用该函数。

现在我要测试send_formatted_email的调用send_email与预期的参数。为此,我试图模拟send_emailusing patch,但它并没有被模拟。

测试文件

@patch('app.util.send_email')
def test_send_formatted_email(self, mock_send_email):
    mock_send_email.return_value = True
    response = send_formatted_email(self.comment, to_email)
    mock_send_email.call_args_list
    ....
Run Code Online (Sandbox Code Playgroud)

视图.py

def send_formatted_email(comment, to_email):
    ...
    message = comment.comment
    subject = 'Comment posted'
    from_email = comment.user.email
    ...
    return send_email(subject, message, to_email, from_email)
Run Code Online (Sandbox Code Playgroud)

实用程序

def send_email(subject, message, to, from):
    return requests.post(
        ...
    )
Run Code Online (Sandbox Code Playgroud)

我什至尝试过,app.util.send_email = MagicMock(return_value=True)但这也不起作用。知道我做错了什么吗?

python python-2.7 python-mock python-unittest

7
推荐指数
1
解决办法
7288
查看次数

Python mock:包装实例方法

我想要什么: 确保Foowith语句中创建的所有实例都foo通过wraps=Foo.foo. 我想要这个的原因是我可以跟踪创建的所有实例call_count的方法。现在我这么说似乎有点不可能......fooFoo

>>> from mock import patch
...
... class Foo(object):
...
...     def foo(self):
...         return "foo"
...
... with patch("__main__.Foo.foo", wraps=Foo.foo) as m:
...     foo = Foo()
...     print(foo.foo())

Traceback (most recent call last):
  File "a.py", line 12, in <module>
    print(foo.foo())
  File "/disk/software/lib/python27/mock/mock.py", line 1062, in __call__
    return _mock_self._mock_call(*args, **kwargs)
  File "/disk/software/lib/python27/mock/mock.py", line 1132, in _mock_call
    return self._mock_wraps(*args, **kwargs)
TypeError: unbound method foo() must be …
Run Code Online (Sandbox Code Playgroud)

python-2.7 python-mock

7
推荐指数
1
解决办法
3144
查看次数

如何创建可下标的 Mock 对象?

假设,我有一个代码片段

foo = SomeClass()
bar = foo[1:999].execute()
Run Code Online (Sandbox Code Playgroud)

为了测试这一点,我尝试了一些

foo_mock = Mock()
foo_mock[1:999].execute()
Run Code Online (Sandbox Code Playgroud)

不幸的是,这引发了一个例外,

类型错误:“模拟”对象不可下标

那么,如何创建可下标的 Mock对象?

python unit-testing mocking python-mock python-unittest

7
推荐指数
1
解决办法
3331
查看次数

我可以向 Python“Mock”对象添加实例方法吗?

我想创建一个mock.Mock()对象,然后添加一个称为session实例方法的方法,该方法传递self对模拟对象的引用,允许该方法向模拟对象添加状态。这是可能的(无需手动使用types.MethodType,例如,使用模拟的内置 API),还是我应该找到解决方法?

请注意,我发现了这个问题,它是针对 Ruby 的,似乎涵盖了类似的内容,如果不是同一件事的话。不幸的是,我根本不了解 Ruby。

python python-mock

6
推荐指数
2
解决办法
7433
查看次数

一种简单的方法来模拟松散定义的Python dict对象

有没有一种简单的方法来在Python中模拟松散定义的dict对象?例如,如何在给定dict的情况下轻松表达input,我想检查其中的每个值是否符合特定的元定义,如最小值和最大值,长度和类型?

能够这样做可能很方便,例如,在编写测试时.

mock(Python版本3.3+中的unittest.mock)中,可以指定值可以是ANY值,例如

>>> mock = Mock(return_value=None)
>>> mock('foo', bar=object())
>>> mock.assert_called_once_with('foo', bar=ANY)
Run Code Online (Sandbox Code Playgroud)

但是,如果bar上面应该是类似dict的对象,就像

>>> {'baz': <an integer between -3 and 14>, 'qux': <'yes' or 'no'>}
Run Code Online (Sandbox Code Playgroud)

python unit-testing python-mock python-unittest

6
推荐指数
1
解决办法
1765
查看次数

如何在python中模拟并仍然允许执行模拟函数的实际代码

我最近开始在 python 中使用模拟框架。似乎如果我修补一个函数,则不会调用实际代码-这意味着未实现此实际函数所做的数据库更改等。我一直试图通过事先调用函数并存储返回值并将其作为 arg 传递到 patch() 来绕过它,但是有没有更好的方法来做到这一点?理想情况下,我想要一个可以用作 a 的代码,silent observer我可以简单地询问它是否observed调用了某个函数,调用了多少次,以及使用了哪些参数

我当前的代码

return_val = funct()

# C: Now call me again and assert that these intensive computation functions are not called but taken from cache
with patch('funct', return_value=return_val) as mock_task:

    me_response = self.client.get(me_url, format='json')    #should fetch from cache
    assert not mock_task.called
Run Code Online (Sandbox Code Playgroud)

python django patch pytest python-mock

6
推荐指数
2
解决办法
2456
查看次数

实例化模拟对象时,模拟属性返回值被覆盖

背景

我正在尝试为我正在编写的应用程序设置一个测试装置,其中我的一个类被模拟替换。我很高兴将模拟类的大部分属性保留为默认MagicMock实例(我只对它们的用法做出断言感兴趣),但该类还有一个属性,我想为其提供特定的返回值.

作为参考,这是我试图修补的类的大纲:

class CommunicationService(object):
    def __init__(self):
        self.__received_response = Subject()

    @property
    def received_response(self):
        return self.__received_response

    def establish_communication(self, hostname: str, port: int) -> None:
        pass

    def send_request(self, request: str) -> None:
        pass
Run Code Online (Sandbox Code Playgroud)

问题

我遇到的困难是,当我修补时CommunicationService,我还尝试为将返回特定值PropertyMockreceived_response属性设置 a 。然而,当我在我的生产代码中实例化这个类时,我发现调用CommunicationService.received_response返回的是默认MagicMock实例而不是我希望它们返回的特定值。

在测试设置期间,我执行以下操作:

context.mock_comms_exit_stack = ExitStack()
context.mock_comms = context.mock_comms_exit_stack.enter_context(
    patch('testcube.comms.CommunicationService', spec=True))

# Make 'received_response' observers subscribe to a mock subject.
context.mock_received_response_subject = Subject()
type(context.mock_comms).received_response = PropertyMock(return_value=context.mock_received_response_subject)

# Reload TestCube module to make it import the …
Run Code Online (Sandbox Code Playgroud)

python mocking python-3.x python-mock

6
推荐指数
1
解决办法
3766
查看次数

mock.patch 忽略完全导入的函数的原因是什么?

今天我意识到unittest.mock.patch如何导入函数很重要。取决于mock.patch呼叫工作或被忽略的使用方式。在 Python 中,我们通常导入一个函数:

  • import os或这样的导入语句
  • from ... import ...像这样的声明from os import system

mock.patch如果我使用A就像一个魅力import os,但如果我修补了它,它会被忽略from os import system

示例 1:使用导入

import os
from unittest import mock


def echo():
    os.system('echo "Hello"')


with mock.patch('os.system') as mocked:
    print(mocked)
    mocked.side_effect = Exception('Patch works!')
    echo()
Run Code Online (Sandbox Code Playgroud)

示例 1 的输出

<MagicMock name='system' id='140037358656760'>

Traceback (most recent call last):
  File "/.../config/scratches/scratch_7.py", line 12, in <module>
    echo()
  File "/.../config/scratches/scratch_7.py", line 6, in echo
    os.system('echo "Hello"')
  File "/.../python3.5/unittest/mock.py", …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-mock python-unittest

6
推荐指数
1
解决办法
1290
查看次数