Mockとは
Mockはテスト時にダミーデータを用意すること。
pythonでは、クラスやメソッドの戻り値をダミーデータにして、テストをするときに使います。
mockライブラリのインストール
pipコマンドでmockのインストールをします。
pip install mock
unittestでMockを使う
まずはMockを使わない場合のunittestの挙動を見てみましょう。
サンプルコード
class Calc: """ テスト対象用クラス 計算クラス """ def tasu(self, a, b): """ 足し算メソッド """ print('tasu') return a + b def hiku(self, a, b): """ 引き算メソッド """ print('hiku') return a - b
import unittest from calc import Calc class TestCalc(unittest.TestCase): def test_tas(self): """足し算 """ c = Calc() ans = c.tasu(1, 2) self.assertEqual(ans, 3) if __name__ == "__main__": unittest.main()
test_calc.py実行結果
tasu . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
サンプルコードは上記のように、Calcのtasuメソッドを使って正常に動くことが確認できました。
では、Mockを使ってtest_calc.pyを書き換えてみましょう。
import unittest from calc import Calc from mock import Mock class TestCalc(unittest.TestCase): def test_tas(self): """足し算 """ c = Calc() # tasuメソッドの処理を空っぽにしている。 c.tasu = Mock() # 戻り値をダミーデータに設定 c.tasu.return_value = 2 ans = c.tasu(1, 2) self.assertEqual(ans, 3) if __name__ == "__main__": unittest.main()
実行結果
F ====================================================================== FAIL: test_tas (__main__.TestCalc) 足し算 ---------------------------------------------------------------------- Traceback (most recent call last): File "d:/study/Python/workspace/unittest/test_calc.py", line 18, in test_tas self.assertEqual(ans, 3) AssertionError: 2 != 3 ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
解説
テストが失敗した結果になりました。
結果を見ると、ansの値が2になって、不一致のためエラーが発生しているようです。
self.assertEqual(ans, 3)
AssertionError: 2 != 3
ansの値が2になった理由は下記のコードで変えているからです。
c.tasu = Mock()
上記は、cのtasuメソッドの中身の処理を空っぽにしています。
戻り値も処理も何もしなくなりますが、tasuメソッドを呼び出す機能だけはそのまま残っている感じです。
c.tasu.return_value = 2
そして上記は、c.tasuメソッドの戻り値を2に変更しています。
この処理でダミーのデータを入れます。
その結果、本来のtasuメソッドで戻り値として渡すはずだった値が、固定値2が入るようになっているため、
AssertionError: 2 != 3
のような結果になるわけです。
何をMock化できるか
上記のサンプルでは、CalcインスタンスのメソッドをMock化していました。
他にも、Mock化できるものがあります。
- クラス
- 上記での例 Calc = Mock()でCalcクラスをMock化する。クラスをMockにすると、そのクラスから生成したインスタンス、生成したインスタンスのメソッドやフィールドもMockとなる。
- クラスからインスタンス生成して変数にいれたもの
- 上記での例 c = Calc() c = Mock() cが持っているすべてのメソッド、フィールドもMock化
- クラスからインスタンス生成し、変数にいれたもので、その変数が持っているメソッド、またはフィールド
- 上記での例 c.tasu = Mock() c.value(selfで持ってる値)
まとめ
- Mockはテスト用のダミーデータを用意する。
- クラスやメソッド、インスタンスをMockにできる。
- ダミーデータはMock化したオブジェクト.return_valueで、戻り値にダミーデータを入れられる。