'function' 对象没有属性 'assert_called_once_with'

'function' object has no attribute 'assert_called_once_with'

我正在尝试 运行 使用 pytest 和 pytest_mock

进行以下测试
def rm(filename):
    helper(filename, 5)

def helper(filename):
    pass

def test_unix_fs(mocker):
    mocker.patch('module.helper')
    rm('file')
    helper.assert_called_once_with('file', 5)

但是我遇到异常AttributeError: 'function' object has no attribute 'assert_called_once_with'

我做错了什么?

您不能在 vanilla 函数上执行 .assert_called_once_with 函数:您首先需要用 mock.create_autospec 装饰器包装它。例如:

<b>import unittest.mock as mock</b>

def rm(filename):
    helper(filename, 5)

def helper(filename):
    pass

<b>helper = mock.create_autospec(helper)</b>

def test_unix_fs(mocker):
    mocker.patch('module.helper')
    rm('file')
    helper.assert_called_once_with('file', 5)

或者更优雅:

import unittest.mock as mock

def rm(filename):
    helper(filename, 5)

<b>@mock.create_autospec</b>
def helper(filename):
    pass

def test_unix_fs(mocker):
    mocker.patch('module.helper')
    rm('file')
    helper.assert_called_once_with('file', 5)

请注意,断言将失败,因为您仅使用 'file' 调用它。所以一个有效的测试是:

import unittest.mock as mock

def rm(filename):
    helper(filename, 5)

@mock.create_autospec
def helper(filename):
    pass

def test_unix_fs(mocker):
    mocker.patch('module.helper')
    rm('file')
    helper.<b>assert_called_once_with('file')</b>

编辑:如果函数是在某个模块中定义的,您可以在本地将其包装在装饰器中。例如:

import unittest.mock as mock
<b>from some_module import some_function</b>

<b>some_function = mock.create_autospec(some_function)</b>

def test_unix_fs(mocker):
    some_function('file')
    some_function.assert_called_once_with('file')

面向对象的情况下:

class Foo:
    def rm(self, filename):
        self.helper(filename, 5)

    def helper(self, filename, number):
        pass

def test_unix_fs(mocker):
    mocker.patch.object(Foo, 'helper')
    foo = Foo()
    foo.rm('file')
    helper.assert_called_once_with('file', 5)