Следите за экземплярами классов и методами - PullRequest
0 голосов
/ 19 мая 2018

Я хочу видеть, как создаются экземпляры классов, и я хочу видеть, как используются методы этого класса.Я могу достичь первой цели, но код ниже демонстрирует, как я не могу шпионить за вызовами методов.Окончательное утверждение не выполнено.

import mock

class A:
    def __init__(self, some_arg):
        print("constructor")

    def f(self, some_var):
        print(some_var)

p = mock.patch('__main__.A', wraps=A)
m = p.start()
A = m
a = A('something')
a.f('my_arg')
assert mock.call('something') in m.mock_calls
assert m.method_calls  # This fails, call to f is not tracked

Если я использую autospec = True, я могу видеть вызовы метода, но тогда сам метод не вызывается.Я хочу, чтобы фактический код выполнялся, я просто хочу шпионить за ним.

Я не могу сделать что-то вроде http://wesmckinney.com/blog/spying-with-python-mocks/, потому что у меня нет экземпляра класса.

1 Ответ

0 голосов
/ 19 мая 2018

Это https://stackoverflow.com/a/41599695/9816369 имеет довольно твердое решение.Исходя из этого, я могу сделать это:

import mock


def spy_decorator(method_to_decorate):
    m = mock.MagicMock()
    def wrapper(self, *args, **kwargs):
        m(*args, **kwargs)
        return method_to_decorate(self, *args, **kwargs)
    wrapper.mock = m
    return wrapper


class A:
    def __init__(self, some_arg):
        print("constructor")

    def f(self, some_var):
        print(some_var)


construct_spy = spy_decorator(A.__init__)
f_spy = spy_decorator(A.f)
p_construct = mock.patch('__main__.A.__init__', construct_spy)
p_f = mock.patch('__main__.A.f', f_spy)

m_construct = p_construct.start()
m_f = p_f.start()

a = A("hi")
a.f("car")

m_construct.mock.assert_called_once_with("hi")
m_f.mock.assert_called_once_with("car")

Это может быть немного лучше, но это довольно солидно.Я должен также упомянуть, что существует https://github.com/beanbaginc/kgb, но я не хотел изменять файл требований, с которым я работаю.

...