adr*_*ino 0 python mocking pytest functools
我正在尝试测试一个被记忆的方法lru_cache(因为它是一个昂贵的数据库调用)。和pytest-mock.
代码的简化版本是:
class User:
def __init__(self, file):
# load a file
@lru_cache
def get(self, user_id):
# do expensive call
Run Code Online (Sandbox Code Playgroud)
然后我正在测试:
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')
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
TypeError: unhashable type: '_ANY'
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为functools.lru_cache需要存储的密钥是可散列的,即有一个方法__hash__或__cmp__实现。
我怎样才能在嘲笑者中嘲笑这些方法以使其工作?
我试过了
user.__hash__.return_value = 'foo'
Run Code Online (Sandbox Code Playgroud)
没有运气。
Lon*_*Rob 11
对于到达这里并试图弄清楚如何测试用lru_cache或修饰的函数的人来说alru_cache,答案是在每次测试之前清除缓存。
这可以按如下方式完成:
def setup_function():
"""
Avoid the `(a)lru_cache` causing tests with identical parameters to interfere
with one another.
"""
my_cached_function.cache_clear()
Run Code Online (Sandbox Code Playgroud)
我相信您不想使用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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1881 次 |
| 最近记录: |