英文:
pytest does not work as expected combined with @cache
问题
I understand your request. Here's the translated code:
问题回复后更新_
我在使用Pytest编写缓存类的单元测试时遇到了问题。我试图使用`mockfunc`来替换下面代码中的`slowfunc`,但是在我使用`@cache`时,补丁似乎只在不使用`@cache`时才成功。
```python
import pytest
from functools import cache
from unittest.mock import patch
@cache
class A:
def __init__(self):
print("calling init")
def slowfunc(self, text):
print("calling slowfunc:", text)
return False
def call(self):
return self.slowfunc("blah")
class B:
def call(self):
a = A()
return a.call()
class Test_B:
def mockfunc(self, text):
print("calling mockfunc:", text)
return True
@patch.object(A, 'slowfunc', mockfunc)
def test_B(self):
b = B()
result = b.call()
assert result == True
if __name__ == "__main__":
retcode = pytest.main(["-xs", __file__])
禁用@cache
并运行代码会得到预期的结果:
example.py calling init
calling mockfunc: blah
.
=== 1 passed in 0.07s ===
启用@cache
时,测试失败:
example.py calling init
calling slowfunc: blah
F
=== FAILURES ===
___ Test_B.test_B ___
self = <example.Test_B object at 0x7f305eaaa1f0>
@patch.object(A, 'slowfunc', mockfunc)
def test_B(self):
b = B()
result = b.call()
> assert result == True
E assert False == True
example.py:27: AssertionError
=== short test summary info ===
FAILED example.py::Test_B::test_B - assert False == True
!!!! stopping after 1 failures !!!
=== 1 failed in 0.23s ===
在这种情况下,slowfunc
被调用,测试失败。发生了什么?在测试开始时使用A.cache_clear()
也无法解决这种情况。
<details>
<summary>英文:</summary>
_Question updated after the reply from larsks_
I'm having trouble writing a unit test in Pytest for a cached class. I'm trying to patch `slowfunc` in the code below with `mockfunc`. However, the patch only appears to succeed when I'm not using `@cache`.
import pytest
from functools import cache
from unittest.mock import patch
@cache
class A:
def init(self):
print("calling init")
def slowfunc(self, text):
print("calling slowfunc:", text)
return False
def call(self):
return self.slowfunc("blah")
class B:
def call(self):
a = A()
return a.call()
class Test_B:
def mockfunc(self, text):
print("calling mockfunc:", text)
return True
@patch.object(A, 'slowfunc', mockfunc)
def test_B(self):
b = B()
result = b.call()
assert result == True
if name == "main":
retcode = pytest.main(["-xs", file])
Running the code with `@cache` commented out gives the expected result:
example.py calling init
calling mockfunc: blah
.
=== 1 passed in 0.07s ===
With `@cache` enabled it fails:
example.py calling init
calling slowfunc: blah
F
=== FAILURES ===
___ Test_B.test_B ___
self = <example.Test_B object at 0x7f305eaaa1f0>
@patch.object(A, 'slowfunc', mockfunc)
def test_B(self):
b = B()
result = b.call()
> assert result == True
E assert False == True
example.py:27: AssertionError
=== short test summary info ===
FAILED example.py::Test_B::test_B - assert False == True
!!!! stopping after 1 failures !!!
=== 1 failed in 0.23s ===
`slowfunc` is called in this case, and the test fails. What's going on? Using `A.cache_clear()` at the start of the test does not resolve the situation either.
</details>
# 答案1
**得分**: 1
虽然我无法为您提供完整的解释,但看起来您可以通过在实例化您的 `A` 对象后修补该函数来解决此问题:
```python
class Test_A:
def mockfunc(self, text):
print("调用 mockfunc:", text)
return True
def test_A(self):
a = A()
with patch.object(a, "slowfunc", self.mockfunc):
result = a.call()
assert result == True
英文:
While I don't have a complete explanation for you, it looks like you can work around this issue by patching the function after instantiating your A
object:
class Test_A:
def mockfunc(self, text):
print("calling mockfunc:", text)
return True
def test_A(self):
a = A()
with patch.object(a, "slowfunc", self.mockfunc):
result = a.call()
assert result == True
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论