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

时间:2019-08-08 11:42:07

标签: python unit-testing pytest pytest-mock

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

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

我需要检查some_method是否已被调用。我已经使用pytest-mock来模拟some_generator方法来返回MagicMock并使用该对象来检查该方法是否被调用。但它返回的是假的。同样,我分配的返回值不会反映到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 个答案:

答案 0 :(得分:1)

我认为您有两个问题:

  1. 您不是在告诉mocker some_generator在哪里。我认为您需要包含一个模块名称。
  2. 您在嘲笑生成器的返回值,而不是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)