模拟白名单其接口
sealedmock的Python项目详细描述
密封模型
列出模拟的属性/方法,而不是让 它创建新的模拟对象。
sealedmock允许指定何时定义模拟,确保 缓存对模拟的任何意外调用。
示例:
fromunittest.mockimportMockfromsealedmockimportsealm=Mock()m.method1.return_value.attr1.method2.return_value=1seal(m)# No new attributes can be declaredm.method1().attr1.method2()# 1m.method1().attr2# Exception: AttributeError mock.method1().attr2
大新闻!这是进入Python3.7!见this PR。
安装
pip install sealedmock
用法
如果您有如下文件:
importurllib2classSampleCodeClass(object):"""This is sample code"""defcalling_urlopen(self):returnurllib2.urlopen("http://chooserandom.com")defcalling_splithost(self):returnurllib2.splithost("//host:port/path")
您可以编写如下测试:
fromunittest.mockimportpatchfromsealedmockimportseal@patch("tests.sample_code.urllib2")deftest_using_decorator(mock):sample=sample_code.SampleCodeClass()mock.urlopen.return_value=2seal(mock)# No new attributes can be declared# calling urlopen succeeds as mock.urlopen has been definedsample.calling_urlopen()# This will fail as mock.splithost has not been definedsample.calling_splithost()
如果使用公共模拟,则第二部分将通过,因为它将创建 嘲笑你然后把它还给你。使用SealedMock,您可以选择何时停止 那种行为。
这是递归的,因此您可以编写:
@patch("sample_code.secret")deftest_recursive(mock):sample=sample_code.SampleCodeClass()mock.secret.call1.call2.call3.return_value=1seal(mock)# No new attributes can be declared# If secret is not used as specified above it will fail# ex: if do_stuff also calls secret.call1.call9sample.do_stuff()
如果像这样使用,它还可以防止测试中的输入错误:
@patch("sample_code.secret")deftest_recursive(mock):sample=sample_code.SampleCodeClass()sample.do_stuff()seal(mock)mock.asert_called_with(1)# Note the typo in asert (should be assert)# A sealed mock will rise, normal mock won't