Python从导入的模块中模拟一个函数

时间:2013-04-21 17:48:08

标签: python unit-testing python-unittest python-mock

我想了解如何@patch来自导入模块的函数。

这是我到目前为止的地方。

应用/ mocking.py:

from app.my_module import get_user_name

def test_method():
  return get_user_name()

if __name__ == "__main__":
  print "Starting Program..."
  test_method()

应用/ my_module / __ INIT __ PY:

def get_user_name():
  return "Unmocked User"

测试/ mock-test.py:

import unittest
from app.mocking import test_method 

def mock_get_user():
  return "Mocked This Silly"

@patch('app.my_module.get_user_name')
class MockingTestTestCase(unittest.TestCase):

  def test_mock_stubs(self, mock_method):
    mock_method.return_value = 'Mocked This Silly')
    ret = test_method()
    self.assertEqual(ret, 'Mocked This Silly')

if __name__ == '__main__':
  unittest.main()

按照我的预期工作。 “修补”模块只返回get_user_name的未标记值。如何模拟我要导入到测试名称空间的其他包中的方法?

2 个答案:

答案 0 :(得分:103)

当您使用patch包中的unittest.mock装饰器时,您修补从中导入模块的命名空间(在本例中为app.my_module.get_user_name)您正在测试app.mocking.get_user_name下的命名空间中修补它。

要使用Mock执行上述操作,请尝试以下操作:

from mock import patch
from app.mocking import test_method 

class MockingTestTestCase(unittest.TestCase):

    @patch('app.mocking.get_user_name')
    def test_mock_stubs(self, test_patch):
        test_patch.return_value = 'Mocked This Silly'
        ret = test_method()
        self.assertEqual(ret, 'Mocked This Silly')

标准库文档包含一个有用的section来描述这个。

答案 1 :(得分:7)

虽然马蒂约翰的回答解决了你的问题(也帮助了我,谢谢!),但是,我会建议本地化替换原来的' get_user_name'与嘲弄的人一起工作。这将允许您控制何时更换功能以及何时更换功能。此外,这将允许您在同一测试中进行多次替换。为此,请使用''以一种非常类似的方式陈述:

from mock import patch

class MockingTestTestCase(unittest.TestCase):

    def test_mock_stubs(self):
        with patch('app.mocking.get_user_name', return_value = 'Mocked This Silly'):
            ret = test_method()
            self.assertEqual(ret, 'Mocked This Silly')