pytest 无法多次模拟同一个模块

pytest unable to mock the same module multiple times

我正在尝试使用 mock 来测试特定功能,出于某些原因,我似乎无法模拟同一个模块两次而且我不明白为什么

a.py

def a():
    return "ok"

b.py

    from sandbox.tests.a import a
    
    
    def b(la):
    
        for i in la:
            a()
    
        return "b"
    
    
    def c():
        a()
        return "c"

我想测试的是 a 的调用量,所以在我的测试中我这样做:


    from mock import patch
    
    
    @patch("sandbox.tests.a.a", return_value="mocked")
    def test_b(mock):
        from sandbox.tests.b import b
    
        b(["1", "2"])
    
        assert mock.call_count == 2
    
    
    @patch("sandbox.tests.a.a", return_value="mocked2")
    def test_b_again(mock):
        from sandbox.tests.b import c
    
        c()
    
        assert mock.call_count == 1

如果我 运行 1 次测试它有效但是当我 运行 2 次测试在一起时我有这个错误:

E       AssertionError: assert 0 == 1
E        +  where 0 = <Mock name='test_2' id='4360227664'>.call_count

令人惊讶的是,如果我在每个函数 b 和 c 中打印 mock 的输出,mock 具有相同的 ID :

a <MagicMock name='a' id='4358021024'> # function b
a <MagicMock name='a' id='4358021024'> # function c 

我也试过给模型起个名字,但它仍然给出相同的 ID


@patch("sandbox.tests.a.a")
def test_b(mock):
    mock = Mock(name="test_1", return_value="test_1")
    from sandbox.tests.b import b

    b(["1", "2"])

    assert mock.call_count == 2


@patch("sandbox.tests.a.a")
def test_b_again(mock):
    mock = Mock(name="test_2", return_value="test_2")
    from sandbox.tests.b import c

    c()

    assert mock.call_count == 1

是否有等同于 jest.resetModules() 的东西,以便我可以模拟两次相同的模块?

谢谢

解决方案是在模块 b 的上下文中修补 a,而不是尝试修补 sandbox.tests.a 'directly'。这是必要的,因为模块 b 仅导入一次 a,而不是在每个函数 bc.

中导入

相反,补丁 sandbox.tests.b.a - 即模块 b:

使用的 a 的 'instance'
@patch("sandbox.tests.b.a", return_value="mocked")
def test_b(self, mock):
    from sandbox.tests.b import b
    
    b(["1", "2"])
    
    assert mock.call_count == 2
    
    
@patch("sandbox.tests.b.a", return_value="mocked2")
def test_c(self, mock):
    from sandbox.tests.b import c

    c()
    assert mock.call_count == 1