lundi 26 octobre 2015

How does @mock.patch know which parameter to use for each mock object?

Looking at this webpage: http://ift.tt/K1Z0Hh -- The author talks about Mocking and Patching in Python and gives a pretty solid "real-world" example. The part that is tripping me up is understanding how the unit testing frame work knows which mock object gets passed to which patch.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)

Code sample is pretty easy to understand. Hard-coded dependency on the OS library/module. First checks if the file exists using the os.path.isfile() method and if so, removes it using os.remove()

Test/Mock code is as follows:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):

    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False

        rm("any path")

        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")

        # make the file 'exist'
        mock_path.isfile.return_value = True

        rm("any path")

        mock_os.remove.assert_called_with("any path")

I guess what's confusing me is that there are 2 @Patch calls and 2 parameters passed in the test. How does the unit testing framework know that mymodule.os.path is patching os.path and that it is mapped to mock_path? And where is mymodule.os.path defined?

(There appears to be a lot of "magic" going on and I'm not following it.)

Aucun commentaire:

Enregistrer un commentaire