インポートされたモジュールから関数を@patch
する方法を理解したい。
これは私がこれまでのところです。
app/mocking.py:
from app.my_module import get_user_name
def test_method():
return get_user_name()
if __== "__main__":
print "Starting Program..."
test_method()
app/my_module/__ init__.py:
def get_user_name():
return "Unmocked User"
test/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 __== '__main__':
unittest.main()
これはnot期待通りに動作します。 「パッチを適用した」モジュールは、単にget_user_name
のモックされていない値を返します。テスト中のネームスペースにインポートしている他のパッケージのメソッドをモックするにはどうすればよいですか?
unittest.mock
パッケージのpatch
デコレーターを使用している場合、モジュールのインポート元のネームスペースにパッチを適用しているnotこの場合は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 が含まれています。
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')