mock(http://mock.readthedocs.org/en/latest/index.html) is a great tool in python for unit test. It can conveniently mock a method or class or dict.But I encountered a problem which I couldn't find a straightforward way to deal with by mock.
This is the function to be tested:
def function_to_be_tested(id, responses):
if not id in responses:
print '%s not exist'%pole_id
return
if id in responses.redundantErrorResponses:
print '%s is redundant'%pole_id
return
do_something()
argument responses is a dict like object which has some other attributes(such as redundantErrorResponses) except dict inherent features. Now I want to construct a mock responses to let id in responses
to be True and id in responses.redundantErrorResponses
to be False. This is what I do:
pole_id = 30
pole_value = 100
pole_dic = {pole_id:pole_value}
mock_responses = MagicMock()
mock_responses.__getitem__.side_effect = lambda k: pole_dic[k]
mock_responses.__iter__.side_effect = iter(pole_dic)
mock_responses.redundantErrorResponses = {}
But error occurred:
function_to_be_tested(pole_id, mock_responses)
>>30 not exist
So how can I construct a MagicMock object meanwhile can iterate like a dict or how can I construct a dict meanwhile support MagicMock features(add attribute freely)?
You can use dict. get method to return the default value of your choice that can mock the existence of is_active entry.
MagicMock has "default implementations of most of the magic methods.". If you don't need to test any magic methods, Mock is adequate and doesn't bring a lot of extraneous things into your tests. If you need to test a lot of magic methods MagicMock will save you some time.
MagicMock objects provide a simple mocking interface that allows you to set the return value or other behavior of the function or object creation call that you patched. This allows you to fully define the behavior of the call and avoid creating real objects, which can be onerous.
mock provides a powerful mechanism for mocking objects, called patch() , which looks up an object in a given module and replaces that object with a Mock . Usually, you use patch() as a decorator or a context manager to provide a scope in which you will mock the target object.
Why mess around with __iter__
? It seems to me that you want to mess with __contains__
:
>>> import mock
>>> m = mock.MagicMock()
>>> d = {'foo': 'bar'}
>>> m.__getitem__.side_effect = d.__getitem__
>>> m.__iter__.side_effect = d.__iter__
>>> m['foo']
'bar'
>>> 'foo' in m
False
>>> m.__contains__.side_effect = d.__contains__
>>> 'foo' in m
True
You can always just create some silly class to do the same thing.
In [94]: class MockResponses(dict):
....: def redundantErrorResponses(self):
....: return {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With