48

テストには Python モック モジュールを使用しています。アクティブなオブジェクトをモックに置き換えて、モック オブジェクトに対して行われたすべての呼び出しを元のオブジェクトに自動的に転送したいと考えています。これは、標準的なテスト用語で「スパイ」と呼ばれていると思います。現時点では、テストの中でやっています:

# Insert a mock replacement
orig_active_attr = server.active_attr
server.active_attr = mock.Mock()

# Set up side effects to 'proxy' to the original object
server.active_attr.meth1.side_effect = orig_active_attr.meth1
server.active_attr.meth2.side_effect = orig_active_attr.meth2

# Call the method being tested
server.method_being_tested()

# Assert stuff on the mock.
server.active_attr.meth2.assert_called_once()

ボイラープレートなしで、モックのすべてのメソッド呼び出しがライブ オブジェクトに自動的に転送されると便利です。

4

5 に答える 5

48

私は解決策に出くわしたようです:

import mock

class A(object):
    def meth(self, a):
        return a
a = A()
ma = mock.Mock(wraps=a)

関数、メソッド、およびプロパティでは問題なく機能するようですが、クラスまたはインスタンス属性では機能しません。

ドキュメントを参照してください。

于 2013-11-21T20:12:30.683 に答える
2

シンプルな関数を使用して、すべてのメソッドを繰り返し処理し、モックを構成できます

def spy_mock(instance):
    members = inspect.getmembers(instance, inspect.ismethod)
    attrs = {'%s.side_effect' % k:v for k,v in members}
    return mock.Mock(**attrs)

使用法は

import inspect
from unittest import mock

class ActiveAttr:

    def meth2(self):
        print("Meth2 called")

class Server:

    def __init__(self):
        self.active_attr = ActiveAttr()

    def method_being_tested(self):
        self.active_attr.meth2()


def spy_mock(instance):
    members = inspect.getmembers(instance, inspect.ismethod)
    attrs = {'%s.side_effect' % k:v for k,v in members}
    return mock.Mock(**attrs)

server = Server()
server.active_attr = spy_mock(server.active_attr)

server.method_being_tested()

server.active_attr.meth2.assert_called_once()
于 2013-09-18T15:04:28.820 に答える