models/client.py 内のクラスのインスタンス変数hogeをmock化したいです。
tests/test.py にテストコードを書いています。
ディレクトリ構成
app/
├ models/client.py
│
└ tests/test.py
ソースコード
大体こんな感じなのだろうなと予想をしております。
python
1# client.py 2class Client(): 3 def __init__(self): 4 # ...色々省略しています... 5 self.hoge = # 外部APIに対するrequestのresponse結果が代入される 6 7 def get_hoge(self): 8 result = # self.hoge をここでごちゃごちゃといじる 9 return result 10 11 # 以下インスタンスメソッドが続きます 12 13 14# test.py 15import unittest 16from unittest.mock import patch 17import models.client as client 18 19class TestClient(unittest.TestCase): 20 def setUp(self): 21 self.client_instance = client.Client() 22 23 def test_get_hoge_method(self): 24 with patch('models.client.???', ???=???): 25 hoge = self.client_instance.get_hoge() 26 self.assertEqual(hoge, 望ましい結果, 'get_hogeがresponseに対して正しく操作を行っていることを確認する')
やりたいこと
テストにおいて実際にAPIに対してrequestしたくないので、self.hogeをmockで仮想responseに置き換える。
試したこと
???
と書いた部分を試行錯誤してなんとかうまく動いてはいるのですが、ものすごく遠回りをしていて、**実際誰もこんな書き方しないだろうな...**というひどいコードになってしまいました。
お願い
ですので、上記の目的を達成できる方法について、ご存知の書き方があれば複数提供いただけると大変嬉しいです。
また、unittestのpatchの書き方を上手く検索することができなかったため、何か良い検索方法をご教示いただけると大変嬉しいです。
ドキュメントの類を見ても、自分の欲しい書き方がどこにあるのか全く分かりませんでした。
たとえばここ
unittest.mock --- 入門¶
追記
インスタンス変数をmockで置き換えることができた例(すごく汚いコード)
(2019/05/02 追記)
python
1# client.py 2 3import abcd.something_api as something_api 4class Client(): 5 def __init__(self): 6 # ...色々省略しています... 7 something_api.Reqetsing(some_object) 8 self.api_response = some_object.response 9 10 def get_hoge(self): 11 # self.api_response をここでごちゃごちゃといじるのですが省略します 12 result = self.api_response['hoge'] 13 return result 14 15 # 以下インスタンスメソッドが続きます 16 17 18# test.py 19import unittest 20from unittest import mock 21from unittest.mock import patch 22import models.client as client 23 24class TestClient(unittest.TestCase): 25 def setUp(self): 26 self.client_instance = client.Client() 27 28 def test_get_hoge_method(self): 29 response_msg = 'dummy_responseです' 30 31 _mock = mock.MagicMock(response={ hoge: response_msg }) 32 with patch('abcd.something_api.Requesting', side_effect=[_mock]): 33 # client.py の `something_api.Reqetsing` も mock で置き換えた 34 with patch('***.***.***', return_value=None): 35 hoge = self.client_instance.get_hoge() 36 37 self.assertEqual(hoge, response_msg, 'get_hogeがresponseに対して正しく操作を行っていることを確認する')
メソッドの細部の書き換えや省略をしているので誤記があるかもしれませんが、ほぼこのような動きです。
インスタンス変数をmock化したい理由
mockとpatchで2回の置き換えを行っているのが不満で、どうにかこれを「1回で済ませたいな」という思いから、インスタンス変数をmock化したいと思っています。
それだけでなくインスタンス変数をmock化する方法自体も純粋に知りたいので、できればメソッドのmock化ではなく、インスタンス変数のmock化の方法を回答いただきたいです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/29 04:14 編集
2019/04/29 12:15 編集
2019/05/06 03:28 編集
2019/05/07 04:55