A little tip for working with the mock library.
Let's say you need to set up some child attributes, like
for example you're mocking up a django.contrib.auth.User
,
and you want it to be a logged in user:
>>> user = mock.Mock()
>>> user.username = 'Bob'
>>> user.is_authenticated.return_value = True
Using it should be straightforward:
>>> user.username
'Bob'
>>> user.is_authenticated
<Mock name='mock.is_authenticated' id='27461840'>
>>> user.is_authenticated()
True
That's all fine, but if you have a lot of attributes to set, it could be
annoying to do each with a separate statement. Fortunately Mock
passes keyword args on to Mock.configure_mock()
which sets them as attributes
on the instance. So here's a shortcut:
>>> user = mock.Mock(username='Bob')
>>> user.is_authenticated.return_value = True
Well, we've saved one line, but can we also save that second line? We can't do
mock.Mock(is_authenticated.return_value=True)
, that'd raise a NameError.
It turns out if you pass a dict to Mock.configure_mock()
, you can use dotted
notation in its keys - and you can do the same with keyword args to
Mock.__init___()
. So that means we can write it all in one line, like so:
>>> user = mock.Mock(**{'username': 'Bob',
... 'is_authenticated.return_value': True})
>>>
>>> user.username
'Bob'
>>> user.is_authenticated()
True
Nice!