Python学習【365日チャレンジ!】197日目のマスターU(@Udemy11)です。
まだまだ暑い日が続いていますが、朝晩が少しだけ過ごしやすくなったような気がします。
日中は相変わらず暑いので、釣りに行くなら、やっぱり夜か朝ですが、大物を狙うなら朝なので、早起きして行こうと思うのですが、なかなか起きられないんですよね。
起きたときにはすでに日が昇っていて、朝マヅメのチャンスには間に合わず、結局釣りに行けなかったなんて日もあります。
かたや気合を入れてバッチリ準備していくと全く反応がなかったり。。。
こういうところが釣りにハマってしまう原因かもしれませんね。
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日はmock.assertの使い方を学習しました。
mockを使うことで、外部サービスの処理をせずに仮想の値を代入してテストができましたが、mock.assertでは、外部サービスを使うメインの関数がきちんと呼ばれているかどうかを確認することができました。
mock.assertの詳細については、こちらの記事をごらんください。
今日は、デコレーターでmock.patchを使う方法を学習します。
salary.py
メインのファイルは昨日と同じsalary.py
です。
import requests
class BonusApi(object):
def bonus_price(self, year):
req = requests.get('http://localhost/bonus', params={'year': year})
return req.json()['price']
class Salary(object):
def __init__(self, base=50, year=2020):
self.bonus_api = BonusApi()
self.base = base
self.year = year
def cal_salary(self):
bonus = self.bonus_api.bonus_price(year=self.year)
return self.base + bonus
test_salary.py
今回のテストファイルでは、MagicMockを使わずにデコレータを使って、引数にテストするメソッドと返り値を指定します。
import unittest
from unittest import mock
import salary
class TestSalary(unittest.TestCase):
@mock.patch('salary.BonusApi.bonus_price', return_value=100)
def test_cal_salary_patch(self, mock_bonus):
s = salary.Salary()
self.assertEqual(s.cal_salary(), 150)
mock_bonus.assert_called()
今回は、MagicMock
ではなく、mock
をインポートしています。
8行目でデコレーターmock.patch
にファイルのパスと返り値を指定して、9行目でテスト関数の引数に変数mock_bonus
を指定します。
10行目と11行目はcal_salary
の計算をテストしていて、12行目で引数のmock.bonus
を使ってbonus.price
が呼ばれているかどうかをテストしています。
ブレークポイントを入れてデバックしてみるとmock.bonus
にbonus_price
のMagicMock
が入っているのがわかります。
test_salary.pyその2
次に、デコレーターに返り値(return_value=100
)を入れずに他の書き方を使って同じことをテストしてみます。
import unittest
from unittest import mock
import salary
class TestSalary(unittest.TestCase):
@mock.patch('salary.BonusApi.bonus_price')
def test_cal_salary_patcher(self, mock_bonus):
mock_bonus.return_value = 100
s = salary.Salary(year=2020)
salary_price = s.cal_salary()
self.assertEqual(salary_price, 150)
mock_bonus.assert_called()
8行目のデコレーターでは、テスト関数を指定していますが、返り値(return_value
)を指定せず、10行目にmock_bonus.return_value = 100
を入れています。
12行目と13行目がメインのコードの処理をしている部分で、15行目、16行目でテストを行っています。
mock
の処理が上下に分かれているため、通常は、上下1行ずつ空白行を入れるのがルールとされているようです。
答えは1つじゃない
基本的にどのような動作をさせるにしても、結果にたどり着くまでの方法は1つしかないわけじゃありません。
単純な計算にしても、足して5になる数字はなにかという問題があれば、1と4でもいいし、2と3でもいいし、1が3つと2が1つでも構わないわけで、-1と6でもいいわけです。
つまり、結果にたどり着く方法はいろいろな方法があって、答えが1つなわけではありません。
答えが必ずある前提の日本の教育を受けてきたわたしたちは、どうしても【正しい答え】を求めてしまいます。
正しい答えなんてものは存在しないことが分かれば、飛躍的に学習効率は上がるので、答えを求めずに自分の好奇心に従って気になったことを試してみることが重要です。
正しい答えという枠にとらわれず、未知の領域へ飛び出してみてください。
それでは明日もGood Python!