How to mock a dictionary in Python
For anyone coming across this later, there is also mock.patch.dict
which can be used as a context manager, decorator, or class decorator.
For example:
from mock import patch
foo = {}
@patch.dict(foo, {"is_active": True})
def test():
assert foo['is_active'] == True
Or to mock os.environ
which is how I came across this question:
import os
from mock import patch
@patch.dict("os.environ", {"FOO": "BAR"})
def test_env():
assert os.environ['FOO'] == "BAR"
How to mock a dictionary in Python is a good/direct question someone else can search, so:
- I suggest MagicMock instead of Mock
- Overload the
__getitem__
from unittest.mock import MagicMock
m = MagicMock()
d = {'key_1': 'value'}
m.__getitem__.side_effect = d.__getitem__
# dict behaviour
m['key_1'] # => 'value'
m['key_2'] # => raise KeyError
# mock behaviour
m.foo(42)
m.foo.assert_called_once_with(43) # => raise AssertionError
Related Questions:
- How to let MagicMock behave like a dict?
- Understanding __getitem__ method
=== EDIT ===
As a function for direct copy/pasting
def mock_dict(d):
m = MagicMock()
m.__getitem__.side_effect = d.__getitem__
return m
You can use this to make a mock behave like a dictionary:
mock = mocker.MagicMock()
mock.__getitem__.side_effect = lambda x: getattr(mock, x)
With that code mock['some_property']
equals to mock.some_property
.
This way you can still use your autogenerated Mock
s so useful for assertions, which is why I didn't like the accepted answer.
If you still need to access the methods of the dictionary then the code will need further work.