如果使用不同的属性多次调用方法,如何模拟方法?
How to mock method if it is getting called multiple times with different attributes?
我正在为我的 Python 和基于 Fabric 的代码编写单元测试。我有以下方法,它依次使用不同的参数多次调用 Fabric API 的 sudo
方法。我想知道如何在模拟 sudo
对象上调用断言。
**main_file.py**
from fabric.api import sudo
def do_something(path_to_file_to_be_copied, destination_path):
# remove file if already exists
sudo('rm ' + path_to_file_to_be_copied, warn_only=True)
sudo('cp ' + path_to_file_to_be_copied + ' ' + destination_path)
我写了如下测试文件:
**test_main_file.py**
import main_file
class MainFileTest(unittest.TestCase):
@mock.patch('main_file.sudo')
def test_do_something(self, mock_sudo):
file_path = '/dummy/file/path.txt'
dest_dir = '/path/to/dest/dir'
main_file.do_something(file_path, dest_dir)
mock_sudo.assert_called_with('rm ' + file_path)
以上测试失败,因为模拟对象只记得最后一次调用。也就是说,如果我写 mock_sudo.assert_called_with(cp + file_path + ' ' + dest_dir)
则测试失败。
如何断言对 sudo
的调用?
尝试 assert_any_call
断言是否有 any 调用,而不仅仅是最近的一个。
或者,您可以使用 call_args_list
获取调用 mock 时使用的参数列表。
assert_has_calls 会为您完成这项工作。
assert_has_calls : assert the mock has been called with the specified calls. The mock_calls list is checked for the calls.
If any_order is true then the calls can be in any order, but they must all appear in mock_calls.
import main_file
class MainFileTest(unittest.TestCase):
@mock.patch('main_file.sudo')
def test_do_something(self, mock_sudo):
file_path = '/dummy/file/path.txt'
dest_dir = '/path/to/dest/dir'
main_file.do_something(file_path, dest_dir)
mock_sudo.assert_has_calls(['rm ' + file_path,
'cp' + file_path + ' ' + dest_dir],
any_order=True)
我写了一个 helper library 来自动为我生成断言。
添加这些行以在 main_file.do_something(file_path, dest_dir)
:
之后为您的案例打印正确的断言
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mock_sudo))
您将得到以下输出:
from mock import call
assert 2 == mock_sudo.call_count
mock_sudo.assert_has_calls(
calls=[call('rm /dummy/file/path.txt', warn_only=True),
call('cp /dummy/file/path.txt /path/to/dest/dir'), ])
不用再猜了,用mock-generator :)
我正在为我的 Python 和基于 Fabric 的代码编写单元测试。我有以下方法,它依次使用不同的参数多次调用 Fabric API 的 sudo
方法。我想知道如何在模拟 sudo
对象上调用断言。
**main_file.py**
from fabric.api import sudo
def do_something(path_to_file_to_be_copied, destination_path):
# remove file if already exists
sudo('rm ' + path_to_file_to_be_copied, warn_only=True)
sudo('cp ' + path_to_file_to_be_copied + ' ' + destination_path)
我写了如下测试文件:
**test_main_file.py**
import main_file
class MainFileTest(unittest.TestCase):
@mock.patch('main_file.sudo')
def test_do_something(self, mock_sudo):
file_path = '/dummy/file/path.txt'
dest_dir = '/path/to/dest/dir'
main_file.do_something(file_path, dest_dir)
mock_sudo.assert_called_with('rm ' + file_path)
以上测试失败,因为模拟对象只记得最后一次调用。也就是说,如果我写 mock_sudo.assert_called_with(cp + file_path + ' ' + dest_dir)
则测试失败。
如何断言对 sudo
的调用?
尝试 assert_any_call
断言是否有 any 调用,而不仅仅是最近的一个。
或者,您可以使用 call_args_list
获取调用 mock 时使用的参数列表。
assert_has_calls 会为您完成这项工作。
assert_has_calls : assert the mock has been called with the specified calls. The mock_calls list is checked for the calls.
If any_order is true then the calls can be in any order, but they must all appear in mock_calls.
import main_file
class MainFileTest(unittest.TestCase):
@mock.patch('main_file.sudo')
def test_do_something(self, mock_sudo):
file_path = '/dummy/file/path.txt'
dest_dir = '/path/to/dest/dir'
main_file.do_something(file_path, dest_dir)
mock_sudo.assert_has_calls(['rm ' + file_path,
'cp' + file_path + ' ' + dest_dir],
any_order=True)
我写了一个 helper library 来自动为我生成断言。
添加这些行以在 main_file.do_something(file_path, dest_dir)
:
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mock_sudo))
您将得到以下输出:
from mock import call
assert 2 == mock_sudo.call_count
mock_sudo.assert_has_calls(
calls=[call('rm /dummy/file/path.txt', warn_only=True),
call('cp /dummy/file/path.txt /path/to/dest/dir'), ])
不用再猜了,用mock-generator :)