如何使用 python 模拟库模拟基类 [英] How to mock a base class with python mock library

查看:27
本文介绍了如何使用 python 模拟库模拟基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 mock 在 python 中编写一些单元测试.

I try to use mock to write some unit-tests in python.

例如我有以下课程:

class TCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()

我只想测试 handle 方法.无需对 socketserver.BaseRequestHandler 做任何假设.例如,我想断言 handle 使用参数 1024 调用 recv.可以用模拟做这样的事情吗?IE.用模拟替换基类 socketserver.BaseRequestHandler?还是我偏离了这个想法?

And I only want to test the handle method. Without having to assume anything about socketserver.BaseRequestHandler. I for example want to assert that handle calls recv with the argument 1024. Is it possible to do such thing with mock? I.e. replacing the base class socketserver.BaseRequestHandler with a mock? Or am I off track with that idea?

在 ecatmur 的回答下(谢谢!)我首先尝试了以下方法:

With the answer of ecatmur (thank you!) I first tried the following:

patcher = patch.object(TCPHandler, '__bases__', (Mock,))
with patcher:
    patcher.is_local = True
    handler = TCPHandler()
    handler.handle()

但是现在 handle 不再被调用并且 dir(handler) 给出:

But now handle is not called anylonger and dir(handler) gives:

['assert_any_call', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect']

type(handler) 给出<class 'mock.TCPHandler'>

我解释说,修补基类也会将我的派生类变成一个模拟类.

Which I interpret that patching the base class also turns my derived class into a mock.

我现在尝试了另一个想法:

I now gave another idea a try:

mock = MagicMock()
TCPHandler.handle(mock)
#assertions

但是模拟似乎没有被调用.

However the mock seems not to be called.

推荐答案

您可以通过修补派生类的 __bases__ 来做到这一点:

You can do this by patching the derived class's __bases__:

def test_derived():
    patcher = mock.patch.object(Derived, '__bases__', (mock.Mock,))
    with patcher:
        patcher.is_local = True
        d = Derived()
        print d.foo()

is_local hack 是阻止 mock.patch 在反转补丁时尝试调用 delattr 所必需的.

The is_local hack is necessary to stop mock.patch from trying to call delattr when reversing the patch.

这篇关于如何使用 python 模拟库模拟基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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