mercredi 10 février 2021

Python mocking function that isn't called directly

In my object, I have several "Loader" functions for different types of data that might require loading. They're stored as:

import foo
import bar

class MyClass
    LOADERS = {
        'foo': {
            'context_manager': False,
            'func': foo.data.loader,
            'kwargs': {'data_orientation': 'columns'}
            },
        'bar': {
            'context_manager': True,
            'func': bar.load_data
            'kwargs': {}
            }
        }

    def load_data(self, load_type, path):
        func = self.LOADERS[load_type]['func']
        kwargs = self.LOADERS[load_type]['kwargs']
        if self.LOADERS[load_type]['context_manager']:
            with open(path, 'rb') as f:
                self.data=func(f, **kwargs)
        else:
            self.data = func(path, **kwargs)

This is working very well in practice, but I'm finding it's murder to test.

When I write my test:

from mock import MagicMock, patch
import sys

sys.modules['foo'] = MagicMock()
sys.modules['bar'] = MagicMock()

from mypackage import MyClass

@patch('foo.data.loader')
def test_load_foo(mock_loader):
    my_obj = MyClass()
    my_obj.load_data('foo', 'path/to/data')
    mock_loader.assert_called_once()

it fails. Called 0 times.

I halfway suspect that it's because it's not being called directly. But that shouldn't really matter.

Can anyone offer any suggestions? I'm using pytest as my testing engine, but I've found it plays nicely with mock in the past.

Thanks!

Aucun commentaire:

Enregistrer un commentaire