首页 > 解决方案 > Pytest 模拟通过 yield 返回的对象并检查该对象的方法是否被调用

问题描述

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

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

我需要检查 some_method 是否已被调用。我曾经pytest-mock模拟 some_generator 方法以返回 aMagicMock并使用该对象来检查该方法是否被调用。但它返回错误。我分配的返回值也没有反映到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)调用了,测试也总是失败。

标签: pythonunit-testingpytestpytest-mock

解决方案


我认为你有两个问题:

  1. 你不说mocker在哪里some_generator。我认为您需要包含一个模块名称。
  2. 您正在模拟生成器的返回值,而不是with 语句__enter__()进行的调用。您不需要单独的模拟对象,已经为任何嵌套属性创建了模拟对象。mockerreturn_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)

推荐阅读