1

I'm tring to use mock to test a specific function, for some reasons it seems that I can't mock twice the same module and I don't understand why

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"

What I want to test is the amount of calls of a are made, so in my test I do :


    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

If I run 1 test it works but when I run the 2 tests together I have this error :

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

Surprisingly if I print the output of the mock in each function b and c, the mock has the same ID :

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

I also tried to put a name on the mock but it stills gives the same 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

Is there an equivalent of jest.resetModules() or something so I can mock twice the same module ?

Thanks

TLd
  • 602
  • 8
  • 23

1 Answers1

1

The solution is to patch a within the context of module b, rather than trying to patch sandbox.tests.a 'directly'. This is necessary because module b imports a only once, rather than in each of functions b and c.

Instead, patch sandbox.tests.b.a - i.e the 'instance' of a which is being used by module b:

@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
match
  • 10,388
  • 3
  • 23
  • 41
  • Works as a charm, very interesting I didn't know about this module context in python. Thanks – TLd Nov 29 '21 at 17:52