Reputation: 1258
I'm attempting to mock a class.
The class I'm attempting to mock looks like the following (lines have been removed for brevity):
class Connection(object):
"""Connection.
"""
def __init__(self, base_url=None, creds=None, user_agent=None):
self.clients = ClientFactory(self)
As you can see, it has a property called clients
.
My method under test:
def _auth(self, credentials):
connection = Connection(base_url=f'https://someurl.com', creds=credentials)
return connection.clients
My unit test looks like this:
@patch('connection.Connection.__init__')
def test_deploy(patched_connection, fs):
patched_connection.return_value = None
patched_connection.clients = None
# Do some stuff
The question is... how do I set the clients
property in my test as the method under test requires it to be set? (I can set it to None
, but I just need to be able to set it.)
With the current code, my application returns the error:
AttributeError: 'Connection' object has no attribute 'clients'
Thanks!
Upvotes: 2
Views: 293
Reputation: 16885
You probably want to patch the Connection
class itself, not the __init__
method:
@patch('connection.Connection')
def test_deploy(patched_connection, fs):
connection_object = MagicMock()
patched_connection.return_value = connection_object
connection_object.clients = None
sut = Auth() # create the tested object (Auth is a placeholder here)
sut._auth('') # call the tested function
# test for how `Connection` was constructed
patched_connection.assert_called_once_with(
base_url='https://someurl.com', creds='')
You patch the Connection
class, and by setting return_value
you set the Connection
instance mock. Now you can set the wanted attributes in that instance.
Note that checking for the __init__
call actually means to check for the instance creation call, so you can use the Connection
mock for that.
This is presuming that you don't want to test Connection
itself, of course, and that _auth
belongs to another class (here called Auth
).
Upvotes: 2