Friday, January 25, 2013

Issues in python unittests using Python Mock

In running some unit tests, my assertions were returning things like

AssertionError: Mock name='mock.RiakClient().bucket().get().get_data()' id='39021008' != 'test-data'

It does this because the object you are mocking doesn't have anything specified to handle the members that are being accessed on it.  That is if you have

x = Mock()
x.y = 'thing'


but you call

x.z
 
Mock will intercept this and create a new mock object with the name 'x.z'.  You can string these along and get a name such as 'x.z.foo().bar()'

The fix to my original issue (the AssertionError) is to simply handle the attribute correctly

x = Mock()
mock_get_data = mock(return_value='test-data')
#one-liner
mock_get = Mock(get=Mock(return_value=mock_get_data)

#more readable two-liner
mock_bucket = Mock()
mock_bucket.bucket = Mock(return_value=mock_get)

x.RiakClient.return_value = mock_bucket




Edit: Added rest of mock object match the example better