2017-10-12 9 views
3

からインポートする方法の中にインポートされた私は、テストに次の関数を得ましたデータベースの名前をとり、そこからコマンド文字列を作成し、このコマンドをsubprocessとしてexecute_cmdメソッドで実行します。 実際にsubprocessを実行せずにこの機能をテストしたいと思います。私は、コマンドが正しく構築され、正しくexecute_cmdに渡されているかどうかを確認したいだけです。したがって、モジュールutilsからインポートされたexecute_cmdメソッドをモックする必要があります。 機能をモックする方法、それは別のモジュール

my_project 
|_src 
| |_my_package 
| | |_db_engine 
| | | |_db_functions.py 
| | | |_ __init__.py 
| | |_utils.py 
| | |_ __init__.py 
| | |_ .... 
| |_ __init__.py 
|_tests 
    |_test_db_engine.py 

は、だから私のテストのために、私は test_db_engine.pyで、次の試してみました:

import unittest 
from mock import patch 

from my_pacakge.db_engine.db_functions import dbinfo 


def execute_db_info_cmd_mock(): 
    return { 
      'Last Checkpoint': '1.7', 
      'Last Checkpoint Date': 'May 20, 2015 10:07:41 AM' 
    } 


class DBEngineTestSuite(unittest.TestCase): 
    """ Tests für DB Engine""" 

    @patch('my_package.utils.execute_cmd') 
    def test_dbinfo(self, test_patch): 
     test_patch.return_value = execute_db_info_cmd_mock() 
     db_info = dbinfo('MyDBNameHere') 
     self.assertEqual(sandbox_info['Last Checkpoint'], '1.7') 

実際のコマンド利回りLast Checkpointため1.6の実行

マイフォルダ構造は次のようです。だから模擬戻り値が使用されているかどうかを確認するために、私は1.7に設定します。 しかし、テストケースの実行は模擬でパッチされているはずの実際の関数を実行しているので、まだ1.6という結果が得られているので、関数のモックは使用されません。

ここで何が間違っていますか?

答えて

3

誤った場所にパッチを適用しています。 Where to patch sectionから:

patch()別のものとに名前ポイントというオブジェクトを変更する(一時的に)の作品。個々のオブジェクトを指す名前が多数ある可能性があるので、パッチを適用するには、テスト対象のシステムで使用されている名前を修正する必要があります。

基本的な原則は、オブジェクトがである箇所を修正して、を検索したものです。これは定義されている場所と必ずしも同じ場所ではありません。

あなたのコード被試験は独自のモジュール内のグローバルとしてexecute_cmdが見つかっていますが、その参照にパッチを適用しませんでした:

from ..utils import execute_cmd 

my_package.utils.execute_cmd参照は、パッチを適用しますが、my_package.db_engine.db_functionsでそのexecute_cmd参照されます元のパッチが適用されていない関数を指しています。

が代わりにインポートされたグローバルなパッチを適用:

@patch('my_package.db_engine.db_functions.execute_cmd') 

dbinfo内部execute_cmdルックアップは、むしろfrom ... import ...文でバインド元世界よりもパッチを当てたモックオブジェクトを使用します。

+0

ありがとうございます、これは正しく機能しました=) – Igle

関連する問題