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

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

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&#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")

def slowfunc(self, text):
    print(&quot;calling slowfunc:&quot;, text)
    return False
    
def call(self):
    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

@patch.object(A, &#39;slowfunc&#39;, 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, &#39;slowfunc&#39;, 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&#39;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(&quot;calling mockfunc:&quot;, text)
        return True

    def test_A(self):
        a = A()
        with patch.object(a, &quot;slowfunc&quot;, self.mockfunc):
            result = a.call()
        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:

确定