1. ホーム
  2. python

[解決済み] python mock - メソッドの実装を妨げずにパッチを適用する

2023-05-16 07:01:02

質問

オブジェクトにパッチを適用して assert_call* ヘルパーを取得できるようにオブジェクトにパッチを適用するきれいな方法はありますか?

例えば、どのようにすれば @patch の行を修正すれば、次のようなテストが通るようになります。

from unittest import TestCase
from mock import patch


class Potato(object):
    def foo(self, n):
        return self.bar(n)

    def bar(self, n):
        return n + 2


class PotatoTest(TestCase):

    @patch.object(Potato, 'foo')
    def test_something(self, mock):
        spud = Potato()
        forty_two = spud.foo(n=40)
        mock.assert_called_once_with(n=40)
        self.assertEqual(forty_two, 42)

を使って、これをハックすることができるかもしれません。 side_effect しかし、私は、関数、クラスメソッド、staticmethods、非結合メソッドなどのすべてで同じように動作する、より良い方法があるだろうと期待していました。

どのように解決するのですか?

あなたと同じような解決策ですが wraps :

def test_something(self):
    spud = Potato()
    with patch.object(Potato, 'foo', wraps=spud.foo) as mock:
        forty_two = spud.foo(n=40)
        mock.assert_called_once_with(n=40)
    self.assertEqual(forty_two, 42)

によると のドキュメントによると :

ラップ : ラップするモックオブジェクトを指定する項目。wrapsがNoneでない場合 を呼び出すと、モックオブジェクトはラップされたオブジェクトに呼び出しを渡します。 (実際の結果を返します)。モックの属性にアクセスすると、ラップされたオブジェクトの対応する属性をラップしたモックオブジェクトが返されます。 の対応する属性をラップしたモックオブジェクトを返します。 の対応する属性をラップしたモックオブジェクトが返されます(したがって、存在しない属性にアクセスしようとすると AttributeErrorが発生します)。


class Potato(object):

    def spam(self, n):
        return self.foo(n=n)

    def foo(self, n):
        return self.bar(n)

    def bar(self, n):
        return n + 2


class PotatoTest(TestCase):

    def test_something(self):
        spud = Potato()
        with patch.object(Potato, 'foo', wraps=spud.foo) as mock:
            forty_two = spud.spam(n=40)
            mock.assert_called_once_with(n=40)
        self.assertEqual(forty_two, 42)