I would like to mock a method to return a test value in one of my mocked classes. The issue I am running into is rather then returning the test value, the mocked method returns an object of type MagicMock.
The code is pretty contrived but illustrates the issue.
SuT (sut.py):
provider = None
class Provider():
def get_data(self):
return 'production data'
def get_provider():
return Provider()
def setup_provider():
global provider
provider = get_provider()
def do_worker():
return provider.get_data()
Test (mocking.py):
import unittest
from mock import MagicMock
import sut
class TestWorker(unittest.TestCase):
def test_worker(self):
provider_mock = MagicMock()
provider_mock.get_data.return_value = 'test data'
sut.get_provider = MagicMock(name='get_provider').return_value = provider_mock
sut.setup_provider()
data = sut.do_worker()
# data comes back as type MagicMock
assert data == 'test data'
You got confused by your chained assignment:
sut.get_provider = MagicMock(name='get_provider').return_value = provider_mock
That assignment binds provider_mock
to both sut.get_provider
and to MagicMock(name='get_provider').return_value
.
In other words, it essentially does this:
sut.get_provider = provider_mock
MagicMock(name='get_provider').return_value = provider_mock
That's not what you wanted. Now sut.get_provider
calls provider_mock
and returns a new MagicMock
object, not the original provider_mock
object.
Separate the assignments:
sut.get_provider = MagicMock(name='get_provider')
sut.get_provider.return_value = provider_mock