2017-11-09 1 views
0

私は基本的な操作を持つカスタムDbクラスを持っています。私はそれを回避しようとしています - __init__私のクラスの私は避けたい実際のDBに接続している(私は単なる単体テストを書くので、実際のDBに接続する必要はない)。pytest:私のクラスの__init__をモックできません

これは私のコードです:

@mock.patch('mydb.Db') 
@pytest.mark.parametrize("input,expected", [ 
    (
     { 
      'key' : "x" , 
      'value' : 5 , 
     } , 
     [ "x = 5" ] 
    ) , 
    ]) 
def test_where_statement(mock_db, input, expected): 
    mock_db.__init__.return_value = None 
    assert expected == mock_db.where(input[ "key"] , input[ "value" ])._condition_list 

それは私がNoneにRETURN_VALUEを設定する行に失敗する - 問題は、次のとおりです。

def test_where_statement(mock_db, input, expected): 
>  mock_db.__init__.return_value = None 
E  AttributeError: 'instancemethod' object has no attribute 'return_value' 

私はinit関数をモックしてからになりたいですwhere関数を実行することができます(たとえば、クエリのwhereステートメントを作成します)。

私には何が欠けていますか?

+0

あなたのテストファイルに 'Db'インポートをパッチしていますか? – dm03514

+0

@ dm03514どういう意味ですか?私はテストファイルの上に 'from mydb import Db'を持っています。 – ghostrider

+0

@ghostrider最新の回答を確認してください。 – erhesto

答えて

1

AFAIKでは、2つの別々のアプローチがあります。 1つは__init__メソッドをあなたのパッチで直接模擬し、期待どおりに動作します(元の__init__は呼び出されません)。

@mock.patch('mydb.Db.__init__', return_value=None) 

現在のアプローチには、代わりに(オブジェクトが既に偽であるように途中で呼び出されない)__init__方法をmock_dbするなし値を割り当てる第二は、インスタンスを取得するために呼び出されmock_dbするRETURN_VALUEを割り当てますDbクラス(mock_db.return_valueはあなたのDbインスタンスのモックバージョンを指しているはずです)、あるいはコードが実行されるときに得られるデフォルトのモックの動作を変更したくない場合はそのままにしておいてください(クラス呼び出し時のAFAIRそのインスタンスを作成するためにMockオブジェクトが自動的に作成されます)。

編集: mydbを適切な場所に偽装する必要があります。経験則は、輸入されている場所ではなく、輸入されている場所を模擬することです。つまり、ファイルmy_package.my_moduleにあるコードをimport mydbにテストする場合は、パッチmy_package.my_module.mydb.Dbが必要です。

グレートリソースに関するモック:はみ出さなければならない最初の事のELI5 mocks explained

一つは、私たちがmymodule.osにあるオブジェクトを模擬するためにmock.patch方法デコレータを使用して、その注入しているということです私たちのテストケースメソッドを模倣する。それはmymodule.osでの参照ではなく、os自体を模倣するほうが理にかなっていませんか?

まあ、Pythonは、モジュールをインポートしたり管理したりするとき、やや卑劣なヘビです。実行時に、モジュールモジュールには独自のoがあり、モジュール内の独自のローカルスコープにインポートされます。したがって、私たちがosを模倣するならば、私たちはmymoduleモジュールにおける模擬の効果を見ません。 これを繰り返すマントラは次のとおりです。

ここでは使用されていないアイテムをモックします。

+0

は最初のものを試しました。私のdbにアクセスしようとしたので__init__が呼び出されたと思います。 – ghostrider

+0

mydbを適切な場所に眠ってもよろしいですか?経験則は、輸入されている場所ではなく、輸入されている場所を模擬することです。つまり、 'import mydb'を持つファイル' my_package.my_module'に置かれたコードをテストする場合は、 'my_package.my_module.mydb.Db'にパッチを当てる必要があります。 – erhesto

関連する問題