[TIP] Mocked subprocess.check_output fails assertion
Chad Slater
chad.slater at gmail.com
Sun Feb 2 13:05:44 PST 2014
I'm having a rather strange problem, and I don't know if I'm doing
something boneheaded, or there's a bug in or limitation with mock.
I'm able to successfully mock a call to subprocess.check_output. When
I attempted to validate that it is called with the correct parameters,
the assert_called_with call fails; however, the printed output of the
failure appears to show that the correct values were called.
An excerpt from the failure:
Expected call: check_output(['pw', 'group', 'add', '-n', 'testgroup',
'-g', '1010', '-M', 'bar'], sdterr=<MagicMock name='subprocess.STDOUT'
id='34418164624'>)
Actual call: check_output(['pw', 'group', 'add', '-n', 'testgroup',
'-g', '1010', '-M', 'bar'], stderr=<MagicMock name='subprocess.STDOUT'
id='34418164624'>)
I'm assuming I'm patching this incorrectly, but looking through the
documentation for mock, I'm not sure I see where I went wrong. Full
details, including the function, and test case, are included below,
including imports, but file paths, group, and modules names have been
changed to protect the guilty.
========================== Function in Module foo.py
==================================
import subprocess
from baz.exceptions import *
def create_group(name, gid):
"""Create a group called `name` with the `gid`. Runs the following command
on the host:
pw group add -n `name` -g `gid` -M bar
:param name: the group name
:type name: `str`
:param gid: the group id
:type gid: `int`
.. Warning:: Use :func:`get_gid` to find a valid gid and avoid potential
security implications or other errors.
"""
cmd = ["pw", "group", "add", "-n", name, "-g", str(gid), "-M", "bar"]
try:
out = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as cpe:
print cpe.output
return False
except OSError as ose:
print ose
return False
return True
========================== Test Module =========================================
import re
from unittest import TestCase
try: # If we're running
Python3, mock is built-in to unnittest
from unittest.mock import patch, mock_open, MagicMock, ANY
except ImportError:
from mock import patch, mock_open, Mock, MagicMock, ANY
from baz.buzz import foo
from bazz.exceptions import *
from bazz.buzz.test.test_data import TEST_DATA1, TEST_DATA2, TEST_DATA3
class TestCreateGroup(TestCase):
@patch('foo.subprocess')
def test_create_group_cmds(self, mock_sp):
name = "testgroup"
gid = 1010
res = executor.create_group(name, gid)
cmd = ["pw", "group", "add", "-n", name, "-g", str(gid), "-M", "bar"]
mock_sp.check_output.assert_called_with(cmd, sdterr=mock_sp.STDOUT)
========================= Test Results =========================================
Failure
Traceback (most recent call last):
File "/path/to/venv/lib/python2.7/site-packages/mock.py", line 1201,
in patched
return func(*args, **keywargs)
File "/path/to/app/test/executor_tests.py", line 234, in
test_create_group_cmds
mock_sp.check_output.assert_called_with(cmd, sdterr=mock_sp.STDOUT)
File "/path/to/venv/lib/python2.7/site-packages/mock.py", line 835,
in assert_called_with
raise AssertionError(msg)
AssertionError: Expected call: check_output(['pw', 'group', 'add',
'-n', 'testgroup', '-g', '1010', '-M', 'bar'], sdterr=<MagicMock
name='subprocess.STDOUT' id='34418164624'>)
Actual call: check_output(['pw', 'group', 'add', '-n', 'testgroup',
'-g', '1010', '-M', 'bar'], stderr=<MagicMock name='subprocess.STDOUT'
id='34418164624'>)
More information about the testing-in-python
mailing list