Answer a question

I have something like this in a python test file:

from mock import patch,
from ..monkey import ook
[...]
@patch('monkey.ook', Mock(return_value=None))
def test_run_ook (self, mock_ook):
    self.assertIsNone(ook())
    mock_ook.run.assert_called_once_with('')

When I run this test, I get a ImportError: No module named monkey. Clearly, the path I am patching is not right. However, I am not sure how to make it right without messing with sys.path or PYTHONPATH.

Any pointers?

Answers

From what I gather, with mock, you need to provide a dotted name when patching. Luckily, every module has access to a special module-level variable __name__ which contains the module's name. Using this, if you want to patch variables local to your module, you should be able to do something like the following:

import mock
import unittest

ook = lambda: "the ook"


class OokTest(unittest.TestCase):

    def test_ook(self):
        with mock.patch(__name__ + '.ook', return_value=None):
            self.assertIsNone(ook())
        self.assertEquals(ook(), "the ook")

    # the patch decorator should work the same way, I just tend to use the
    # context manager out of personal preference
    @mock.patch(__name__ + '.ook', return_value=None)
    def test_ook_2(self, mock_ook):
        self.assertIsNone(ook())

Assuming you've saved that file as quicktest.py, the unit tests give this result:

$ python -m unittest quicktest
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

And of course, from a.b import c gives you a plain variable c in your package, so this same mechanism should work.

Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐