Pythonはreturn_valueの代わりにMagicMockオブジェクトを返します


93

a.py2つのクラスAとを含むPythonファイルがありますB

class A(object):
    def method_a(self):
        return "Class A method a"

class B(object):
    def method_b(self):
        a = A()
        print a.method_a()

をあざけることmethod_bでクラスでユニットテストをしたいと思います。この目的のためのファイルの内容は次のとおりです。BAtesta.py

import unittest
import mock
import a


class TestB(unittest.TestCase):

    @mock.patch('a.A')
    def test_method_b(self, mock_a):
        mock_a.method_a.return_value = 'Mocked A'
        b = a.B()
        b.method_b()


if __name__ == '__main__':
    unittest.main()

Mocked Aは出力を取得することを期待しています。しかし、私が得るものは次のとおりです。

<MagicMock name='A().method_a()' id='4326621392'>

私はどこで間違っているのですか?


1
テスト時にA()return_valuefrom mock_A(通常のMagicMockに、クラスのインスタンスではない、他に何も指定していないA。がreturn_value定義されているものに設定する必要がありmethod_aます。
jonrsharpe 2016

3
mock_a.method_a.return_value = 'モックA' => mock_a()。method_a.return_value = 'モックA'の方が良いはずです:)
Ali SAID OMAR

@AliSAIDOMARは正確に正しいです、それは呼び出しからの戻り値です mock_amock_aです。それ自体ではなく、メソッドを持つ必要があるのはです。
jonrsharpe 2016

1
@jonrsharpe。説明ありがとうございます。試したところです。両方mock_a().method_a.return_value = 'Mocked A'mock_a.return_value.method_a.return_value = 'Mocked A'働いた。コメントありがとうございます。先に進んで答えていただけませんか?
Mehdi Jafarnia Jahromi 2016

@MehdiJafarniaJahromiどうもありがとう!
ナイアクロス2018年

回答:


105

の場合@mock.patch('a.A')Aテスト対象のコードのクラスをmock_a。に置き換えます。

B.method_b、あなたその後、設定a = A()今ある、a = mock_a()-つまりはaあるreturn_valuemock_a。この値を指定していないので、これは通常の値MagicMockです。これも構成されていないため、MagicMockメソッドを呼び出すとデフォルトの応答(さらに別の)が返されます。

代わりに、適切なメソッドを持つようreturn_valueofmock_aを構成する必要があります。これは、次のいずれかとして実行できます。

mock_a().method_a.return_value = 'Mocked A' 
    # ^ note parentheses

または、おそらくもっと明確に:

mock_a.return_value.method_a.return_value = 'Mocked A'

この場合a = A(インスタンスを作成するのではなく、クラスを割り当てる)でコードが機能し、a.method_a()モックメソッドがトリガーされます。


4
驚くばかり。あなたは私の日を作りました。
Vishal 2018

こんにちは@jonrsharpe、私はパンダのデータフレームを使用しています フレームを使用してif条件をチェックしています。括弧は使用しません(つまり、呼び出し可能ではありません)。その場合、リストを返すにはどうすればよいですか。ありがとう!
imsrgadich 2018

@imsrgadichそのためのモックが必要ですか?適切なデータフレームを作成し、それをテスト値として扱うだけです。
jonrsharpe 2018

@jonrsharpeええ、私はそれを行うことができましたが、アサートする必要がある呼び出されたメソッドでdf.dropも実行しており、呼び出されたメソッドからデータフレームを返していません。それは問題を引き起こします。私は使用する方法を見つけましたmock_data.configure_mock(columns='my_column')それを解決。返信ありがとうございます。(参照:bradmontgomery.net/blog/how-world-do-you-mock-name-attribute
imsrgadich 2018

同じテストで2つのSQLAlchemyモデルをモックする場合、これは機能しないようです。最初のものは問題なく動作しますが、2番目のものは定義内容に関係なくMagicMockを返します。
JuhaUntinen18年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.