Python学習【365日チャレンジ!】201日目のマスターU(@Udemy11)です。
朝晩が随分過ごしやすくなってきたので、釣りに行きたい欲求がふつふつと湧いてきています。
と言いつつ、早朝から海にでかけてしまっているのですが、なかなか釣果に恵まれないんですよね。
釣れても1匹とかなので、ほんとがっくりして、また釣りに行きたくなるんです。
天候もいい感じになってきているので、そろそろ爆釣してもいい頃なんですが、いつになればそんなおいしい目をみられるんでしょうか?
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日は、side_effect
で例外処理やリストを使った使い方を学習しました。
side_effect
を使ってサーバーにアクセスできないConnectionRefusedErrorなどもテストで処理ができるので、結果を参考にして、メインファイルにバグがないように作り変えていくこともできました。
また、リストを使って外部サービスを複数回呼び出したテストを実行したりできました。
詳細については、こちらの記事をごらんください。
今日は、クラスをまるごとmock化することができるspec
を学習します。
salary.py
メインファイル(salary.py
)は、昨日エラーコードの対応を追加したファイルを使います。
test_cal_salary.py
テストファイルは、デコレーターを使ってメインファイルのクラスをまるごとmock化したコードにします。
import unittest
from unittest import mock
import salary
class TestSalary(unittest.TestCase):
@mock.patch('salary.BonusApi', spec=True)
def test_cal_salary_class(self, MockRest):
mock_rest = MockRest.return_value
mock_rest.bonus_price.return_value = 100
s = salary.Salary(year=2020)
salary_price = s.cal_salary()
self.assertEqual(salary_price, 150)
mock_rest.bonus_price.assert_called()
8行目でメインファイル(salary.py
)のBonusApi
クラスを指定して、引数spec
にTrue
を代入します。
9行目のテスト関数には、クラスなのでキャメルケースで変数MockRest
を指定します。
10行目は、mock_rest = MockRest()
とも記述できますが、公式ドキュメントには上記の書き方でオブジェクトを生成する方法が推奨されています。
11行目でbonus_price
の返り値に100を代入して、その後のコードはこれまで同様で、最後にbonus_price
が呼ばれたかどうかをテストしています。
関数を追加して確認
クラス全体がmock化されているか確認するために、メインファイル(salary.py
)とtest_salary.py
にコードを付け足します。
salary.py
class BonusApi(object):
def check_mock(self):
return 'Clear'
def bonus_price(self, year):
req = requests.get('http://localhost/bonus', params={'year': year})
return req.json()['price']
test_salary.py
mock_rest.check_mock.return_value = 'Yes!'
メインのファイルには簡単なClear!
を返すcheck_mock
という関数を追記して、テストファイルには、check_mock
にYes!
を代入してテストしています。
スペルミスなどがなければテストにパスします。
これまで何度もテストを実行してきましたが、うまくいかないときは、恥ずかしながらスペルミスが原因でした。
講座の内容をたどりながらコードを書いているので、まずはスペルミスがないか確認しましょう。
また、あまり意味がありませんが、テストで代入したYes!
がcheck_mock
に入っているかどうかを確認するには、次のコードを追加します。
c_mock = mock_rest.check_mock.return_value
self.assertEqual(c_mock, 'Yes!')
Yes!
を入れたcheck_mock
を変数c_mock
に代入して、それがYes!
かどうかをチェックしています。
ほんと意味があるのかないのかよくわかりませんが、このコードを追加してもテストはパスします。
試してみることは大切
これまでも何度も自分に言い聞かせていますが、試すことが非常に重要です。
酒井さんの講座の内容をそのまま写経することは勉強にはなりますが、そこから自分なりのコードを書いてみることで学習した内容の理解が深まります。
講座を受講したり、写経するだけではわからなかったことも自分なりに考えながら、試してみることでわからなかったことがわかったり、こんなこともできるのかと気づいたりできるので、あえてこんなことする人はいないだろうと思うことを試してみるとおもしろいかもしれませんよ。
ぜひ、いろいろなコードを試して失敗してみてください。
それでは、明日もGood Python!