Mock configuration tip

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!