Mockのpatchの勘違い
良くわからないけど唐突に意識高くなったので俺ブログ書くわ!!!ブログ書くわ!!! けど後2分くらいしかきっと持たない!!!早く書くんだ俺!!!2分後にはまた死んだ魚ような目になってしまうぞ!
という訳でPythonのMockで小一時間ハマったネタを書く。
前提
まずこんな感じで fuga.pyをimportして利用したhoge.pyをテストするhogetests.pyがあるとする。
# fuga.py # -*- coding: utf-8 -*- def piyo(): return 'piyopiyo'
# hoge.py # -*- coding: utf-8 -*- from fuga import piyo def hogecall(): return piyo() if __name__ == "__main__": print hogecall() # => piyopiyo
# hogetests.py # -*- coding: utf-8 -*- import random import unittest from mock import patch class HogeTests(unittest.TestCase): def _getTargetFunc(self): from hoge import hogecall return hogecall def test_hogecall(self): hogecall = self._getTargetFunc() self.assertEqual(hogecall(), "piyopiyo") if __name__ == '__main__': unittest.main()
やりたい事
ここで hogecallの中で読んでるpiyo()て関数をモック化したい。
def hogecall(): return piyo() # <= コイツをモック化したい
間違った
最初はmock.patchを利用してこのように書いた
@patch('fuga.piyo', return_value="hogehoge") def test_hogecall2(self, piyo): hogecall = self._getTargetFunc() self.assertEqual(hogecall(), "hogehoge")
だがこれはうまく行かず hogehogeが欲しいのにpiyopiyoばっかり帰ってきやがる。無茶しやがって。
正解
正解は patchに噛ます対象が、fuga.piyoではなく、hoge.piyoだった。patchで指定する時は、実際の処理で使われてる関数を置き換えるというものらしい。
@patch('hoge.piyo', return_value="hogehoge") #<= × fuga.piyo ○ hoge.piyo def test_hogecall2(self, piyo): hogecall = self._getTargetFunc() self.assertEqual(hogecall(), "hogehoge")
余談
- hogeとかpiyoとかhogehogeとかpiyopiyoとかもう書いてる本人も良くわからない。多分大体あってる