Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test function with lru_cache decorator

I'm attempting to test a a method that is memoized through lru_cache (since it's an expensive database call). with pytest-mock.

A simplified version of the code is:

class User:

    def __init__(self, file):
        # load a file

    @lru_cache
    def get(self, user_id):
        # do expensive call

Then I'm testing:

class TestUser:

    def test_get_is_called(self, mocker):
        data = mocker.ANY
        user = User(data)
        repository.get(user_id)
        open_mock = mocker.patch('builtins.open', mocker.mock_open())
        open_mock.assert_called_with('/foo')

But I'm getting the following error:

TypeError: unhashable type: '_ANY'

This happens because functools.lru_cache needs the keys stored to be hashable i.e. have a method __hash__ or __cmp__ implemented.

How can I mock such methods in a mocker to make it work?

I've tried

user.__hash__.return_value = 'foo'

with no luck.

like image 482
adrpino Avatar asked Feb 16 '26 11:02

adrpino


1 Answers

For people arriving here trying to work out how to test functions decorated with lru_cache or alru_cache, the answer is to clear the cache before each test.

This can be done as follows:

def setup_function():
    """
    Avoid the `(a)lru_cache` causing tests with identical parameters to interfere
    with one another.
    """
    my_cached_function.cache_clear()
like image 95
LondonRob Avatar answered Feb 18 '26 00:02

LondonRob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!