pepoluan
pepoluan

Reputation: 6808

Mocking a module function called by a static method does not work

Okay so I have a series of Python3 code that looks like this:


foo.py

from bar import ClassB

class ClassA:

    @staticmethod
    def get_all(fn):
        something = ClassB(fn)
        return something.lines()

bar.py

def baz(f):
    with open(f, 'rt') as fin:
        ln = fin.readlines()
    return ln

class ClassB:

    def __init__(self, f):
        self._baz = baz(f)

    def lines():
        return self._baz

Now I write a unit test like this:

test_foo.py

from unittest import TestCase, mock
from foo import ClassA

class Test_A(TestCase):

    @mock.patch("bar.baz")
    def setUp(self, mock_baz):
        mock_baz.return_value = ['a', 'b']

    def test_1(self):
        self.assertEqual(ClassA.get_all('whatever'), ['a', 'b']

Problem:

Running the test causes FileNotFoundError, which means that mock.patch("bar.baz") does not work.

How do I fix this so that the baz() function gets mocked properly?

Upvotes: 0

Views: 3666

Answers (1)

mfrackowiak
mfrackowiak

Reputation: 1304

It seems that your patch does not apply in your test - the function you are mocking is only mocked in the setUp itself. You can try one of two solutions:

Create the patch manually in setUp:

class Test_A(TestCase):

    def setUp(self):
        mock_baz = mock.Mock(return_value=['a', 'b'])
        self.baz_patch = mock.patch("bar.baz", mock_baz)
        self.baz_patch.start()

    def tearDown(self):
        self.baz_patch.stop()
    ...

Or, mock it only in your test:

class Test_A(TestCase):

    @mock.patch("bar.baz")
    def test_1(self, mock_baz):
        mock_baz.return_value = ['a', 'b']
        self.assertEqual(ClassA.get_all('whatever'), ['a', 'b']

Upvotes: 3

Related Questions