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

Cri*_*jon 4 python mocking pytest python-3.x

我正在尝试使用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)
Run Code Online (Sandbox Code Playgroud)

但我得到例外 AttributeError: 'function' object has no attribute 'assert_called_once_with'

我究竟做错了什么?

Wil*_*sem 7

你不能.assert_called_once_withvanilla函数上执行函数:首先需要用mock.create_autospec装饰器包装它.例如:

import unittest.mock as mock

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

def helper(filename):
    pass

helper = mock.create_autospec(helper)

def test_unix_fs(mocker):
    mocker.patch('module.helper')
    rm('file')
    helper.assert_called_once_with('file', 5)
Run Code Online (Sandbox Code Playgroud)

或者更优雅:

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.assert_called_once_with('file', 5)
Run Code Online (Sandbox Code Playgroud)

请注意,断言将失败,因为您只能使用它来调用它'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.assert_called_once_with('file')
Run Code Online (Sandbox Code Playgroud)

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

import unittest.mock as mock
from some_module import some_function

some_function = mock.create_autospec(some_function)

def test_unix_fs(mocker):
    some_function('file')
    some_function.assert_called_once_with('file')
Run Code Online (Sandbox Code Playgroud)


Cri*_*jon 5

面向对象的情况下:

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)
Run Code Online (Sandbox Code Playgroud)

  • 最后一行应该是“foo.helper...”吗? (5认同)