質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

Q&A

解決済

1回答

3403閲覧

[Python3 unittest] importしたモジュールをmockで置き換え、assert_called_with()を使いたい

siruku6

総合スコア1382

import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

0グッド

0クリップ

投稿2020/05/09 12:09

編集2020/05/09 12:12

やりたいことは題名の通りです。
より具体的に書くと、次のソースコード中の、orders.OrderCreate()メソッドに渡された引数をテストしたいです。

※ソースコード及びテストコードは、大分簡略化しているので、このままでは動かない可能性があります

テスト対象のソースコード

python

1# target.py 2 3from oandapyV20 import API 4import oandapyV20.endpoints.orders as orders 5 6 7class TargetClass(): 8 def __init__(self): 9 self.__api_client = API(access_token='hoge', environment='practice') 10 11 def target_method(number_str): 12 data = {'hoge': int(number_str)} 13 # テストしたい部分: このメソッドに渡された引数をテストしたい 14 # data引数に渡された値をテストしたい(実際はめんどうな変換を色々しているが、サンプルとしてinteger型への変換を掲載しています) 15 request_obj = orders.OrderCreate(accountID='hoge', data=data) 16 17 response = self.__api_client.request(request_obj) 18 return response

試したこと(テストコード)

patch を使って次のようなことを試してみましたが、うまくいきませんでした。

python

1# tests/test_target.py 2 3import target 4import unittest 5from unittest.mock import patch, MagicMock 6 7 8class TestClient(unittest.TestCase): 9 @classmethod 10 def setUpClass(cls): 11 cls.__client = target.TargetClass() 12 13 def test_order_args(self): 14 data = {'hoge': 111} 15 16 orders_mock = MagicMock() 17 with patch('oandapyV20.endpoints.orders', return_value=orders_mock): 18 self.__client.target_method('111') 19 20 orders_mock.OrderCreate.assert_called_with('hoge', data)

実行結果

bash

1$ pytest tests 2 3# 略 4 5E AssertionError: expected call not found. 6E Expected: OrderCreate('hoge', {'hoge': 111}) 7E Actual: not called. 8 9# 略

not called とあるので、OrderCreateの引数が一致しなかったのではなく、そもそもorders_mock.OrderCreateが呼ばれていないという状態です。
なので、patchの書き方が間違っている、ということまではわかっています。
ですが、どうかけば正しい書き方になるのかがわかっていません。(patchはよく使っているのですが...)

その他

時間がないため、掲載したソースの動作確認をすることが今はできないのですが、動くようにする必要があれば修正したいと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

そもそもorders_mock.OrderCreateが呼ばれていないという状態です。

patchのreturn_value が orders_mock を返すようになっていて、
orders_mockからは何も呼ばれていません。

同様に patchのreturn_valueにMagicMock()を指定したコードでエラーを確認後、

  • patchの return_value と モック生成 (with patch ... as)
  • assert_called_withの引数

にて修正を確認出来ました。


patchにrturn_valueを指定する場合

# ※ patch対象はOrderCreate(関数) # (1) return_value は、orders.OrderCreate 呼び出しで期待する戻り値 # 必要ならば実際に期待する値に置き換え # (2) with patch(...) as mock: with patch('oandapyV20.endpoints.orders.OrderCreate', return_value=111) as mock: self.__client.target_method('111') # (3) キーワード引数 # print(mock.mock_calls) で確認 mock.assert_called_with(accountID='hoge', data=data)

モジュールにパッチを充てる場合は

python

1with patch('oandapyV20.endpoints.orders') as orders_mock: 2 # 必要ならば、return_valueを設定 3 # orders_mock.OrderCreate.return_value = 111 4 self.__client.target_method('111') 5 6orders_mock.OrderCreate.assert_called_with(accountID='hoge', data=data)

ライブラリはインストールしてません。
orders.py に関数 OrderCreateを仮実装して動作確認後に、
パッチの文字列を 'oandapyV20.endpoints.orders' に置き換えました。

投稿2020/05/09 14:07

teamikl

総合スコア8760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siruku6

2020/05/10 01:57 編集

回答ありがとうございます! モジュールにパッチを充てる場合は 、  `with patch('module_name', return_value=mock_method):` ではなく、  `with patch('module_name') as mock_method:` なのですね! (そして、return_valueをつかうときは、また違う書き方になるんですね) 試してみますので、結果報告まで少々お待ちください...
siruku6

2020/05/14 10:23

ありがとうございます! 示していただいたパターンのうち with patch('oandapyV20.endpoints.orders.OrderCreate', return_value=111) as mock: の書き方で無事テストすることができました! 大変助かりました。 今後もテストの書き方を学んでいきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問