How can I mock/patch an associative array in python
Question: I have a module with a dictionary as associative array to implement a kind-of
switch statement.

    
    
    def my_method1():
        return "method 1"
    
    
    def my_method2():
        return "method 2"
    
    
    map_func = {
        '0': my_method1,
        '1': my_method2
    }
    
    def disptach(arg):
      return map_func[arg]()
    

How can I mock my_method1 in tests? I've tried the following without success:

    
    
    import my_module as app
    
    @patch('my_module.my_method1')
    def test_mocking_sample(self, my_mock):
        my_mock.return_value = 'mocked'
        assert_equal('mocked',app.dispatch('0'))
    

Any idea?


Answer: This piece of
[patch](http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch)
documentation says the following:

> patch works by (temporarily) changing the object that a name points to with
> another one. There can be many names pointing to any individual object, so
> for patching to work you must ensure that you patch the name used by the
> system under test.

Basically, your dispatcher won't see it, as the mapping is built to reference
the original method, before the patch is applied.

The simplest thing you can do to make it mockable is to fold the mapping into
the `dispatch` function:

    
    
    def dispatch(arg):
      return {
        '0': my_method1,
        '1': my_method2
      }[arg]()
    

This does have the downside that it rebuilds that mapping every time you call
it, so it will be slower.

Trying to get a bit clever, it seems that Python lets you swap out the actual
code of a function, like so:

    
    
    >>> f = lambda: "foo"
    >>> a = f
    >>> g = lambda: "bar"
    >>> f.func_code = g.func_code
    >>> a()
    'bar'
    

I won't recommend that you do it this way, but maybe you can find a mocking
framework that supports something similar.

