🎃
Pythonのunittest.mock.patchの対象指定方法について
テストを書いていると、一部の関数をモック化したいということがよくあります。Pythonではunittest.mock.patch
でそれが可能です。
ただ、自分はフロントエンドの実装を行う機会が多く、jsのテストを書く場合はJestを使っているのですが、jest.mock
とunittest.mock.patch
ではモック対象とする関数の指定方法が異なるため、数時間ハマってしまいました。
備忘録ついでにその違いについて書いておきます。
Jestの場合
公式ドキュメント(https://jestjs.io/docs/ja/jest-object#jestmockmodulename-factory-options )に記載されているように、Jestの場合はモックしたいモジュールのパスを引数に指定します。
jest.mock('../moduleName', () => {
return jest.fn(() => 42);
});
unittest.mock.patchの場合
unittest.mock.patch
はデコレータであり、テスト関数の定義の上に記述します。
また、Jestとは違い、モック対象としたい関数が展開されるファイルのパスを指定する必要があります。簡単な例として、以下を考えます。
utils.py
def example_func():
return 10
main.py
from utils import example_func
def main():
return example_func()
main()
test_main.py
import unittest
from main import main
class TestMain(unittest.TestCase):
def test_main(self):
self.assertEqual(main(), 10)
テスト実行時にmain
関数内のexample_func
をモック化したい場合、patchデコレータを以下のように書く必要があります。
def mock_example_func():
return 1
@patch('main.example_func', mock_example_func)
def test_main(self):
self.assertEqual(main(), 1)
importパスを引数に指定するJestとは異なり、unittest.mock.patchではモック対象の関数が展開されるファイルパスを指定する必要があります。
Jestに慣れている人からすると想定外なので、ハマって余計な時間が取られないように注意が必要です。。。
Discussion