pytest-在构造函数中模拟构造函数

时间:2019-07-15 15:07:50

标签: python-3.x pytest pytest-mock

全部

我有一个与此类似的课程。

from mod import Bar

class Foo:
  def __init__(self):
    self.obj = Bar()

如何使用pytest / pytest-mock模拟Bar构造函数?我尝试了以下失败。

def test():
  with mock.patch('mod.Bar') as patched:
    Foo()

2 个答案:

答案 0 :(得分:1)

您必须修补名称,而不是实例。

摘自Python官方文档:Where to patch

  

patch()通过(临时)将名称指向的对象更改为另一个对象来工作。可以有许多名称指向任何单个对象,因此,要使修补程序起作用,必须确保修补受测系统使用的名称。

在您的示例中,类Foo是在模块foomod.py中定义的,因此您必须修补foomod.Bar而不是mod.Bar

您可以使用mocker中的pytest-mock灯具或unittest.mock.patch将其放入灯具。

@pytest.fixture # With pytest-mock
def mock_bar(mocker):
    return mocker.patch('foomod.Bar')

@pytest.fixture # With stdlib
def mock_bar():
    with patch('foomod.Bar') as mock:
        yield mock

# Usage
def test_foo(mock_bar):
    pass

据我所知,两种方法之间没有显着差异。当灯具超出范围时,都将对其进行清理。

答案 1 :(得分:0)

我使用以下代码来模拟带有 pytest 的对象而没有 fixture 装饰器

# path.to.MyClass
class MyClass():
    def __init__(self, some_parameter: SomeObject) -> None:
        self.some_value = some_parameter

    def get_something(self) -> str:
        return 'Hello'


# tests.py
from pytest_mock.plugin import MockerFixture
from unittest.mock import MagicMock

def test_with_mock(mocker: MockerFixture) -> None:
    mock_myclass: MagicMock = mocker.patch('path.to.MyClass')

    mock_myclass_get_something: MagicMock = mocker.patch('path.to.MyClass.get_something')
    mock_myclass_get_something.return_value = 'World!'

    assert mock_myclass.get_something() == 'World!'