14

I'm on python 3.3 and I have to test a method which use call from subprocess.py.

I tried:

subprocess.call = MagicMock()

with patch('subprocess.call') as TU_call:

but in debug mode I found that python call effectively subprocess.call

Joshua Grigonis
  • 748
  • 5
  • 18
beyrem
  • 437
  • 1
  • 3
  • 12
  • [This thread](http://stackoverflow.com/questions/5166851/intercepting-subprocess-popen-call-in-python) might be relevant to your question, though it is about python-2.x. But I guess there has not been that much change. – Emilia Bopp Oct 18 '13 at 12:12
  • What specifically do you mean with "debug mode"? – cfi Jan 03 '14 at 18:56

2 Answers2

11

Works fine for me (Ubuntu 13.04, Python 3.3.1):

$ python3.3
Python 3.3.1 (default, Sep 25 2013, 19:29:01) 
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mock
>>> import subprocess
>>> result = subprocess.call('date')
Fri Jan  3 19:45:32 CET 2014
>>> subprocess.call = mock.create_autospec(subprocess.call, return_value='mocked!')
>>> result = subprocess.call('date')
>>> print(result)
mocked!
>>> subprocess.call.mock_calls
[call('date')]

I believe this question is about the usage of this particular mock package

General statements, unrelated to your direct question

Wrote this up before I understood that the question is specifically about the use of the python mock package.

One general way to mock functions is to explicitly redefine the function or method:

$ python3.3
Python 3.3.1 (default, Sep 25 2013, 19:29:01) 
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.call('date')
Fri Jan  3 19:23:25 CET 2014
0
>>> def mocked_call(*a, **kw):
...   return 'mocked'
... 
>>> subprocess.call = mocked_call
>>> subprocess.call('date')
'mocked'

The big advantage of this straightforward approach is that this is free of any package dependencies. The disadvantage is that if there are specific needs, all the decision making logic has to be coded manually.

As an example of mocking packages, FlexMock is available for both Python 2.7 and Python 3.* and its usage of overriding subprocess.call is discussed in this question

Community
  • 1
  • 1
cfi
  • 10,915
  • 8
  • 57
  • 103
0

This work for subprocess.check_output in python3

    @mock.patch('subprocess.check_output', mock.mock_open())
    @mock.patch('subprocess.Popen.communicate')
    def tst_prepare_data_for_matrices(self, makedirs_mock, check_output_mock):
        config_file = open(os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)+'/etc/test/config.json')).read()
        check_output_mock.return_value = ("output", "Error")