【问题标题】:Mocking third-party function inside class method在类方法中模拟第三方函数
【发布时间】:2020-02-05 22:22:00
【问题描述】:

这可能是一个微不足道的问题,但我找不到合适的解决方案,也不知道如何解决。我简化了问题,所以我有两个文件 my_module.pytest_module.py 在同一个本地化。

import numpy as _np


class MyClass:

    def __init__(self) -> None:
        self.attribute = 1
        self.method()

    def method(self) -> None:
        arr = _np.arange(9).reshape(-1, 3)
        self.attribute = 2
from unittest.mock import Mock, patch

import pytest

from my_module import MyClass


@pytest.fixture
def init_mock():
    with patch.object(MyClass, '__init__', return_value=None) as init:
        yield init


@pytest.fixture
def method_mock():
    with patch.object(MyClass, 'method') as method:
        yield method


@pytest.fixture
def my_class_init_mock(init_mock):
    yield MyClass()


@pytest.fixture
def my_class_method_mock(method_mock):
    yield MyClass()


def test_init(my_class_method_mock):
    assert my_class_method_mock.attribute == 1


def test_method(my_class_init_mock):
    my_class_init_mock.method()
    assert my_class_init_mock.attribute == 2

两项测试全部通过。此外,我需要检查是否使用 -1, 3 参数调用了一次 _np.arange(9).reshape。我发现我应该从my_module.py直接引用numpy。我试图在最后一个测试上方添加@patch('my_module._np')。我还尝试将模块的夹具传递给my_class_method_mock 的夹具。不幸的是,当我触发.method() 函数时,我无法调用这个模拟。如何在它们之间建立联系?

【问题讨论】:

    标签: python mocking pytest patch fixtures


    【解决方案1】:

    这可以通过定义_np 的fixture 并检查是否调用了这个模拟来实现:

    @pytest.fixture
    def numpy_mock():
        with patch('my_module._np') as numpy:
            yield numpy
    
    ...
    
    def test_method(my_class_init_mock, numpy_mock):
        my_class_init_mock.method()
        numpy_mock.arange.assert_called_once_with(9)
        numpy_mock.arange().reshape.assert_called_once_with(-1, 3)
        assert my_class_init_mock.attribute == 2
    

    请注意,我们可以断言方法链的每一部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-10
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多