我想了解如何从导入的模块@补丁函数。

这是目前为止我所处的位置。

应用程序/ 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()

这并不像我预期的那样工作。“patched”模块只是返回get_user_name的未模拟值。如何模拟正在导入到测试中的名称空间中的其他包中的方法?


当前回答

除了Matti John的解决方案,你也可以在app/mock .py中导入模块而不是函数。

# from app.my_module import get_user_name
from app import my_module

def test_method():
  return my_module.get_user_name()

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

其他回答

虽然Matti John的回答解决了您的问题(也帮助了我,谢谢!),但我建议将原始的“get_user_name”函数替换为模拟的函数。这将允许您控制何时替换函数,何时不替换函数。另外,这将允许您在同一个测试中进行多个替换。为了做到这一点,以非常类似的方式使用'with'语句:

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')

当你使用来自unittest的补丁装饰器时。你要在测试中的命名空间(在本例中是app. Mock .get_user_name)中修补模拟包,而不是函数导入的命名空间(在本例中是app.my_module.get_user_name)。

要做到你所描述的@patch,尝试如下所示:

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')

标准库文档中有一个有用的部分描述了这一点。

除了Matti John的解决方案,你也可以在app/mock .py中导入模块而不是函数。

# from app.my_module import get_user_name
from app import my_module

def test_method():
  return my_module.get_user_name()

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