Pytest 模拟通过 yield 返回的对象并检查是否调用了该对象的方法

Pytest mock an object returned via yield and check whether a method of that object is called

我有一段代码需要通过pytest进行测试

def my_function(value):
  with some_generator() as gen:
    gen.some_method(value)

我需要检查 some_method 是否已被调用。我已经使用 pytest-mock 将 some_generator 方法模拟为 return a MagicMock 并使用该对象检查是否调用了该方法。但它是 returning 错误的。我分配的 return 值也没有反映到 some_method

def test_myfunction(mocker):
    generator = mocker.patch('some_generator')
    mocked_obj = mock.MagicMock()
    generator.return_value = mocked_obj
    my_function(1)
    assert mocked_obj.some_method.called

即使调用了 gen.some_method(value),测试总是失败。

我认为你有两个问题:

  1. 你没有告诉 mocker some_generator 在哪里。我认为您需要包含一个模块名称。
  2. 您正在模拟生成器的 return 值,而不是 with statement 进行的 __enter__() 调用。您不需要单独的模拟对象,mocker 已经为 return_value 和任何嵌套属性创建了一个模拟对象。

这是测试的固定版本:

from scratch import my_function

def test_myfunction(mocker):
    generator = mocker.patch('scratch.some_generator')
    my_function(1)
    assert generator.return_value.__enter__.return_value.some_method.called

为了完整起见,这里是我使用的 my_function 的可运行版本:

# scratch.py

def some_generator():
    pass


def my_function(value):
  with some_generator() as gen:
    gen.some_method(value)