0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Python unittest.mockのpatchでランダムな処理をテストする方法

Posted at

概要

以下のようにランダムな処理を含む関数やメソッドを単体テストしたいときに、unittest.mockのpatchが使えます。

import random

def roulette(call_number: int) -> int:
    """
    1~10までの数字が書かれたルーレットで、数字を当てるゲームを表した関数
    """
    if random.randint(1, 10) == call_number:
        return 1000
    else:
        return 0

環境

  • Python3.11

unittest.mockを使わない場合の課題

概要に記載したコードを例に進めます。

すなおに処理を書くと次のようになります。ただ、roulette()内でrandom.randint()を使っているため、roulette()の引数として渡している数字と、random.randint()で返される数字が同じになるか不確実です。

import unittest
import roulette

class TestRoulette(unittest.TestCase):
    def test_equal_call_number(self):
        self.assertEqual(roulette(5), 1000)  # 5 == random.randint(1, 10)は不確実

    def test_not_equal_call_number(self):
        self.assertEqual(roulette(5), 0)  # 5 != random.randint(1, 10)は不確実

unittest.mockのpatchを使う

unittest.mockのpatchはこのような場合に使えます。

import unittest
import roulette


class TestRoulette(unittest.TestCase):
    @patch("random.randint")
    def test_equal_call_number(self, mock_randint):
        mock_randint.return_value = 5
        self.assertEqual(roulette(5), 1000)  # 5 == random.randint(1, 10)は確実

    @patch("random.randint")
    def test_not_equal_call_number(self, mock_randint):
        mock_randint.return_value = 1
        self.assertEqual(roulette(5), 0)  # 5 != random.randint(1, 10)は確実

@patch("random.randint")とすると、random.randintのモック用インスタンスが返されます。これはmock_randint引数に代入されます(引数名は自由)。

その後、モック用インスタンスのインスタンス変数return_valueへ戻り値にしたい値を入れます。
この戻り値はrandom.randintの戻り値となります。
そのためmock_randint.return_value = 5とすればrandom.randint(1, 10)は必ず5を返します。

このようにすることで、ランダムな処理を含んでいる場合でも単体テストを行えます。

参考

How can I test functions, which use random?
ランダムな処理を含む単体テストの例

patch
Python公式ドキュメントunittest.mockのpatch

Pythonのデコレータを理解するまで
デコレーターに関する詳しい説明

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?