如何使用abc抽象基类作为模拟规范?

时间:2017-02-28 18:32:53

标签: python python-mock abc

我有一个抽象的基类:

import abc
import six

@six.add_metaclass(abc.ABCMeta)
class A(object):

    @abc.abstractmethod
    def f(self, arg1):
        pass

我想将此类用作模拟的规范。

import mock
mock_a = mock.Mock(spec=A)

这部分有效。例如,mock_a.x会产生AttribureError("Mock object has no attribute 'x')。但是mock_a.f不是基于A.f的抽象方法而设定的。无论传递给f的参数数量是多少,它都会返回一个模拟。

mock_a = mock.Mock(spec=A)

# Succeeds
print mock_a.f(1)

# Should fail, but returns a mock
print mock_a.f(1,2)

# Correctly fails
print mock_a.x

模拟可以使用create_autospec创建一个A.f的模拟...

f_spec = mock.create_autospec(A.f)

# Succeeds
f_spec(mock_a, 1)

# Correctly fails
f_spec(mock_a, 1, 2)

...但是对于A

的属性没有这样做

如何创建一个精确实现抽象基类的模拟?

1 个答案:

答案 0 :(得分:3)

mock.create_autospec()应用于班级:

>>> mock_a = mock.create_autospec(spec=A)
>>>
>>> # Should succeed
>>> print mock_a.f(1)
<MagicMock name='mock.f()' id='140401932347984'>
>>>
>>> # Should fail
>>> print mock_a.f(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/mock/mock.py", line 1061, in __call__
    _mock_self._mock_check_sig(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mock/mock.py", line 227, in checksig
    sig.bind(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/mock/mock.py", line 95, in fixedbind
    return self._bind(args, kwargs)
  File "/usr/lib/python2.7/dist-packages/funcsigs/__init__.py", line 712, in _bind
    raise TypeError('too many positional arguments')
TypeError: too many positional arguments
>>>
>>> # Should fail
>>> print mock_a.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/mock/mock.py", line 716, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'x'
>>>