I am writing unit tests for my Python and Fabric based code. I have following method which in turn calls sudo
method of Fabric API multiple times with different arguments. I would like to know how to call assert on mock sudo
object.
**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)
I have written test file as below :
**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)
Above test fails because mocked object remembers only last call. that is, if I write mock_sudo.assert_called_with(cp + file_path + ' ' + dest_dir)
then test fails.
How can I assert both the calls to sudo
?
Try assert_any_call
which asserts whether there has been any call, not just the most recent one.
Or, you can use call_args_list
to get the list of args the mock has been called with.
assert_has_calls will do the job for you.
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)
I wrote a helper library to automatically generate the asserts for me.
Add those lines to print the correct asserts for your case, right after main_file.do_something(file_path, dest_dir)
:
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mock_sudo))
You would get the following output:
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'), ])
No need to guess anymore, use mock-generator :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.