スポンサーリンク

[python] unittestをMockを使って行う

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で、戻り値にダミーデータを入れられる。

関連記事