Evan Gui
Evan Gui

Reputation: 795

Why can't directly mock object in unittest?

I'm new to python mocking. I know we can use mock.patch to mock f1 for f2 testing. Like this:

def f1(x):
    return x

def f2(x):
    return f1(x) + 5

class ExampleTest(unittest.TestCase):

    @mock.patch('__main__.f1')
    def test_f2(self, mock_f1):
        mock_f1.return_value = 0
        self.assertEqual(f2(5), 5)

But I found if I directly mock f1 in test case like below, it doesn't work. I have no idea why can't just directly mock "f1" at here?

class ExampleTest(unittest.TestCase):

    def test_f2(self):
        f1 = mock.Mock()
        f1.return_value = 0
        self.assertEqual(f2(5), 5)

Upvotes: 0

Views: 50

Answers (2)

Michele d'Amico
Michele d'Amico

Reputation: 23711

Even patch and Mock are in the same package they have a different duties:

  1. By mock.Mock() you are creating a mock object f1 (local variable)
  2. By patch('__main__.f1') you are patching f1 reference in __main__ module (the one you are running)

patch default behavior is to use mocks to replace the original reference, but you can use it also for installing stubs or fakes: the main duty is to control the context where you replace the reference.

Just a tip: take a look to where to patch ... it can enlightening you.

Upvotes: 1

Daniel Roseman
Daniel Roseman

Reputation: 599490

Not sure why you think that would work. All you're doing is defining a new local variable called f1 which happens to be an instance of Mock; just as if you'd defined f1 = "foo" it doesn't affect the module-level name at all.

Upvotes: 3

Related Questions