M. Buil
M. Buil

Reputation: 569

Getting return value problems with unittest patch() in python

I am trying to use mock.patch to unittest my code, however I am getting a strange result. This is the important part of the code:

@mock.patch('benchmark.scenarios.networking.feature.ssh')
@mock.patch('benchmark.scenarios.networking.feature.subprocess.call')
def test_run_for_success(self, mock_subprocess, mock_ssh):
    mock_ssh.SSH().execute.return_value = (0, '100', '')
    mock_subprocess.call().return_value = 'mocked!'

    result = {}
    self.feature.run(result)

When I run ssh in my code, I get the returned value: (0, '100', ''), good! However, when I run subprocess.call() I get as returned value:

<MagicMock name='subprocess.call()' id='139806699670096'>

What am I doing wrong? I would like to get 'mocked!' as returned value.

Upvotes: 0

Views: 1896

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124798

You are using mock.return_value wrong, and on the wrong object; whenever you want to set the return value for foo(), use foo.return_value, not foo().return_value. Moreover, mock_subprocess points to subprocess.call already, don't look up the call attribute on that!

In other words, don't call the mock object when setting return_value, and use mock_subprocess directly:

mock_subprocess.return_value = 'mocked!'

You may want to rename mock_subprocess to mock_subprocess_call or similar to make that it obvious what you patched.

You were setting a return value for subprocess.call.call()(), not subprocess.call().

Demo:

>>> import subprocess
>>> from unittest.mock import patch
>>> with patch('subprocess.call') as mock_subprocess:
...     mock_subprocess.call().return_value = 'mocked!'
...     print(subprocess.call(), subprocess.call.call()())
...     mock_subprocess.return_value = 'mocked!'
...     print(subprocess.call())
...
<MagicMock name='call()' id='4557171960'> mocked!
mocked!

Upvotes: 4

Related Questions