Dingus有点像模拟对象。主要区别在于您不会提前设置期望。您只需使用Dingus来运行代码代替另一个对象或类,它将记录发生的情况。然后,一旦行使代码,您就可以对其对Dingus的所作所为做出断言。
由Dingus类创建了新的Dingus。您可以给Dinguses名称,这有助于调试测试,尤其是在玩多个Dinguses时。
>>> from dingus import Dingus >>> d = Dingus( ' root ' ) >>> d <Dingus root>
访问Dingus的任何属性都将返回新的Dingus。
>>> d.something <Dingus root.something>
特殊的Dingus方法有一些例外。我们会稍微看到一些。
Dingus也可以称为函数或方法。它不在乎您给出多少论点或这些论点是什么。无论参数如何,呼叫dingus总是会返回同一对象。
>>> d() <Dingus root()> >>> d( ' argument ' ) <Dingus root()> >>> d( 55 ) <Dingus root()>
在任何时候,我们都可以获取对Dingus的电话列表。呼叫列表中的每个条目都包含:
这是我们到目前为止拨打D的电话的列表:
>>> from pprint import pprint >>> pprint(d.calls) [('()', (), {}, <Dingus root()>), ('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
您可以按名称,参数和关键字参数过滤:
>>> pprint(d.calls( ' () ' , 55 )) [('()', (55,), {}, <Dingus root()>)]
如果您不关心特定参数的值,则可以在过滤时使用值dontcare:
>>> from dingus import DontCare >>> pprint(d.calls( ' () ' , DontCare)) [('()', ('argument',), {}, <Dingus root()>), ('()', (55,), {}, <Dingus root()>)]
Dinguses可以做的不仅仅是访问和调用属性。他们支持许多Python运营商。目标是允许并记录任何互动:
>>> d = Dingus( ' root ' ) >>> ( 2 ** d.something)[ ' hello ' ]() / 100 * ' foo ' <Dingus root.something.__rpow__[hello]().__div__.__mul__>
(希望您的现实世界中的录音不会看起来像这样!)
Dingus为测试期间修补对象提供了上下文管理器。例如:
>>> from dingus import patch >>> import urllib2 >>> with patch( ' urllib2.urlopen ' ): ... print urllib2.urlopen. __class__ <class 'dingus.Dingus'> >>> print urllib2.urlopen. __class__ <type 'function'>
您也可以将其用作测试方法上的装饰器:
>>> @ patch( ' urllib2.urlopen ' ) ... def test_something ( self ): ... pass ...
斑块的相反是孤立。它修补除指定对象以外的所有内容:
>>> from dingus import isolate >>> @ isolate( ' urllib2.urlparse ' ) ... def test_urlparse ( self ): ... pass ...
当此测试运行时,Urllib2模块中的所有内容都将是一个兴奋剂。请注意,如果模块包含许多对象,则执行可能会很慢。欢迎性能补丁。 :)
运行测试时,Dingus还可以自动替换模块的全球群体。这使您可以编写完全隔离的单元测试。有关示例,请参见示例/urllib2/test_urllib2.py。作者不再推荐此功能,因为它可以鼓励非常脆弱的测试。您应该感觉到手动嘲笑依赖的痛苦;当班级与其他太多其他人合作时,痛苦会告诉您。