pytest与@cache结合使用时无法按预期工作。

huangapple go评论101阅读模式
英文:

pytest does not work as expected combined with @cache

问题

I understand your request. Here's the translated code:

  1. 问题回复后更新_
  2. 我在使用Pytest编写缓存类的单元测试时遇到了问题我试图使用`mockfunc`来替换下面代码中的`slowfunc`但是在我使用`@cache`补丁似乎只在不使用`@cache`时才成功
  3. ```python
  4. import pytest
  5. from functools import cache
  6. from unittest.mock import patch
  7. @cache
  8. class A:
  9. def __init__(self):
  10. print("calling init")
  11. def slowfunc(self, text):
  12. print("calling slowfunc:", text)
  13. return False
  14. def call(self):
  15. return self.slowfunc("blah")
  16. class B:
  17. def call(self):
  18. a = A()
  19. return a.call()
  20. class Test_B:
  21. def mockfunc(self, text):
  22. print("calling mockfunc:", text)
  23. return True
  24. @patch.object(A, 'slowfunc', mockfunc)
  25. def test_B(self):
  26. b = B()
  27. result = b.call()
  28. assert result == True
  29. if __name__ == "__main__":
  30. retcode = pytest.main(["-xs", __file__])

禁用@cache并运行代码会得到预期的结果:

  1. example.py calling init
  2. calling mockfunc: blah
  3. .
  4. === 1 passed in 0.07s ===

启用@cache时,测试失败:

  1. example.py calling init
  2. calling slowfunc: blah
  3. F
  4. === FAILURES ===
  5. ___ Test_B.test_B ___
  6. self = <example.Test_B object at 0x7f305eaaa1f0>
  7. @patch.object(A, 'slowfunc', mockfunc)
  8. def test_B(self):
  9. b = B()
  10. result = b.call()
  11. > assert result == True
  12. E assert False == True
  13. example.py:27: AssertionError
  14. === short test summary info ===
  15. FAILED example.py::Test_B::test_B - assert False == True
  16. !!!! stopping after 1 failures !!!
  17. === 1 failed in 0.23s ===

在这种情况下,slowfunc被调用,测试失败。发生了什么?在测试开始时使用A.cache_clear()也无法解决这种情况。

  1. <details>
  2. <summary>英文:</summary>
  3. _Question updated after the reply from larsks_
  4. I&#39;m having trouble writing a unit test in Pytest for a cached class. I&#39;m trying to patch `slowfunc` in the code below with `mockfunc`. However, the patch only appears to succeed when I&#39;m not using `@cache`.

import pytest
from functools import cache
from unittest.mock import patch

@cache
class A:
def init(self):
print("calling init")

  1. def slowfunc(self, text):
  2. print(&quot;calling slowfunc:&quot;, text)
  3. return False
  4. def call(self):
  5. return self.slowfunc(&quot;blah&quot;)

class B:
def call(self):
a = A()
return a.call()

class Test_B:
def mockfunc(self, text):
print("calling mockfunc:", text)
return True

  1. @patch.object(A, &#39;slowfunc&#39;, mockfunc)
  2. def test_B(self):
  3. b = B()
  4. result = b.call()
  5. assert result == True

if name == "main":
retcode = pytest.main(["-xs", file])

  1. Running the code with `@cache` commented out gives the expected result:

example.py calling init
calling mockfunc: blah
.

=== 1 passed in 0.07s ===

  1. 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>

  1. @patch.object(A, &#39;slowfunc&#39;, mockfunc)
  2. def test_B(self):
  3. b = B()
  4. 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 ===

  1. `slowfunc` is called in this case, and the test fails. What&#39;s going on? Using `A.cache_clear()` at the start of the test does not resolve the situation either.
  2. </details>
  3. # 答案1
  4. **得分**: 1
  5. 虽然我无法为您提供完整的解释,但看起来您可以通过在实例化您的 `A` 对象后修补该函数来解决此问题:
  6. ```python
  7. class Test_A:
  8. def mockfunc(self, text):
  9. print("调用 mockfunc:", text)
  10. return True
  11. def test_A(self):
  12. a = A()
  13. with patch.object(a, "slowfunc", self.mockfunc):
  14. result = a.call()
  15. 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:

  1. class Test_A:
  2. def mockfunc(self, text):
  3. print(&quot;calling mockfunc:&quot;, text)
  4. return True
  5. def test_A(self):
  6. a = A()
  7. with patch.object(a, &quot;slowfunc&quot;, self.mockfunc):
  8. result = a.call()
  9. assert result == True

huangapple
  • 本文由 发表于 2023年4月6日 21:46:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75950275.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定