什么是spec和spec_set

35 投票
2 回答
29925 浏览
提问于 2025-04-18 17:23

我正在使用 Mock 1.0.1 这个 Python 库。在路径函数的定义中,有两个可选的参数,分别叫做 spec 和 spec_set(还有一个叫 auto_spec)。

patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

我看过文档,但没有找到它们的解释。也许它们是测试相关的术语?如果有人能提供一些信息就太好了,谢谢。

2 个回答

-1

你可以在这里找到更多信息:http://www.voidspace.org.uk/downloads/mock-1.0.1.pdf

• spec:这个可以是一个字符串列表,也可以是一个现有的对象(比如类或实例),用来作为模拟对象的规范。如果你传入一个对象,那么会通过调用这个对象的 dir 方法来生成一个字符串列表(不包括不支持的特殊属性和方法)。如果你访问的属性不在这个列表里,就会出现 AttributeError 错误。如果 spec 是一个对象(而不是字符串列表),那么class 会返回这个 spec 对象的类。这让模拟对象可以通过 isinstance 测试。

• spec_set:这是 spec 的一个更严格的版本。如果使用了这个,试图在模拟对象上设置或获取一个不在作为 spec_set 传入的对象上的属性时,会出现 AttributeError 错误。

39

在Python 3.x中,unittest.mockmock基本上是一样的。

根据unittest.mock的说明:

spec:这个可以是一个字符串列表,也可以是一个现有的对象(类或实例),它用来作为模拟对象的规范。如果你传入一个对象,那么会通过调用这个对象的dir方法来生成一个字符串列表(不包括不支持的特殊属性和方法)。如果你访问的属性不在这个列表中,就会抛出一个AttributeError(属性错误)。

如果spec是一个对象(而不是字符串列表),那么_class_会返回这个spec对象的类。这让模拟对象可以通过isinstance测试。

spec_set:这是spec的一个更严格的版本。如果使用了这个,尝试在模拟对象上设置或获取一个不在spec_set对象中的属性会抛出AttributeError。


更新specspec_set之间的区别。

使用spec时,你可以设置未指定的属性,而使用spec_set时,不允许设置未指定的属性。

示例:

>>> from unittest.mock import Mock
>>> class A:
...     def __init__(self, a, b):
...         self.a = a
...         self.b = b
...
>>> aobj = A(1, 2)



>>> m = Mock(spec=aobj)   # spec
>>> m.c   # get -> fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python3/3.6.0b4_3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 582, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'c'
>>> m.c = 9  # set -> success
>>> m.c      # get -> success (although c is not in the spec)
9



>>> m = Mock(spec_set=aobj)   # spec_set
>>> m.a
<Mock name='mock.a' id='4544967400'>
>>> m.b
<Mock name='mock.b' id='4545493928'>
>>> m.c   # get -> fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python3/3.6.0b4_3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 582, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'c'
>>> m.c = 9  # set -> fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python3/3.6.0b4_3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/mock.py", line 688, in __setattr__
    raise AttributeError("Mock object has no attribute '%s'" % name)
AttributeError: Mock object has no attribute 'c'

撰写回答