监视类实例化和方法 [英] Spying on class instantiation and methods

查看:32
本文介绍了监视类实例化和方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够看到类是如何实例化的,并且我想看到如何使用该类的方法.我可以完成第一个目标,但是,下面的代码演示了我如何无法监视方法调用.最终断言失败.

I want to be able to see how classes are instantiated and I want to see how how methods of that class are used. I can accomplish the first goal, but, the code below demonstrates how I can't spy on the method calls. The final assert fails.

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 我可以看到方法调用,但是实际的方法没有被调用.我想要实际的代码运行,我只是想窥探一下.

If I use autospec=True I can see the method calls, but then the actual method isn't called. I want the actual code to run, I just want to spy on it.

我不能做类似http://wesmckinney.com/blog/spying-with-python-mocks/ 因为我没有该类的实例.

I can't do something like http://wesmckinney.com/blog/spying-with-python-mocks/ because I don't have an instance of the class.

推荐答案

这个https://stackoverflow.com/a/41599695/9816369 有一个非常可靠的解决方案.由此,我可以做到这一点:

This https://stackoverflow.com/a/41599695/9816369 has a pretty solid solution. From that, I can do this:

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 但我没有我不想修改我正在使用的需求文件.

It could be a bit nicer, but this is pretty solid. I should also mention that there is https://github.com/beanbaginc/kgb but I didn't want to modify the requirements file I'm working with.

这篇关于监视类实例化和方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆