Тестовая функция с декоратором lru_cache - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь протестировать метод, который запоминается через lru_cache (так как это дорогой вызов базы данных). с pytest-mock.

Упрощенная версия кода:

class User:

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

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

Тогда я тестирую:

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')

Но я получаю следующую ошибку:

TypeError: unhashable type: '_ANY'

Это происходит потому, что для functools.lru_cache необходимо, чтобы хранимые ключи были хешируемыми , т. Е. Реализован метод __hash__ или __cmp__.

Как я могу издеваться над такими методами в макере, чтобы он работал?

Я пробовал

user.__hash__.return_value = 'foo'

без удачи.

1 Ответ

0 голосов
/ 29 января 2019

Вместо использования mocker.ANY (объект, который предполагается использовать в утверждениях в качестве заполнителя, равного любому объекту), я полагаю, что вместо этого вы хотите использовать сторожевой объект (например, mocker.sentinel.DATA).

Это похоже на быстрый тест:

from functools import lru_cache

@lru_cache(maxsize=None)
def f(x):
    return (x, x)


def test(mocker):
    ret = f(mocker.sentinel.DATA)
    assert ret == (mocker.sentinel.DATA, mocker.sentinel.DATA)
...