Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to let MagicMock behave like a dict?

Tags:

python

mocking

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 responsesto 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)?

like image 586
lengxuehx Avatar asked May 20 '15 04:05

lengxuehx


People also ask

How do you mock a dictionary in python?

You can use dict. get method to return the default value of your choice that can mock the existence of is_active entry.

Should I use mock MagicMock?

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.

How does Magic mock work?

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.

What does mock mock () do?

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.


2 Answers

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
like image 70
mgilson Avatar answered Oct 17 '22 13:10

mgilson


You can always just create some silly class to do the same thing.

In [94]: class MockResponses(dict):
   ....:     def redundantErrorResponses(self):
   ....:         return {}
like image 23
Greg Avatar answered Oct 17 '22 14:10

Greg