我有两个以下文件:
testcase_module.py
import boto3
ec2 = boto3.resource('ec2')
def f():
return ec2.instances.all()
testcase_test.py
import testcase_module
import unittest.mock
class MainTest(unittest.TestCase):
@unittest.mock.patch('testcase_module.ec2', spec_set=['instances'])
def test_f(self, ec2_mock):
ec2_mock.instances.spec_set = ['all']
testcase_module.f()
if __name__ == '__main__':
unittest.main()
我在补丁中添加了spec_test
参数,因为我想断言是否调用了除instances.all()
以外的任何其他函数,但是将字符串'all'
更改为'allx'
并不是将'instances'
更改为'instancesx'
时,测试失败。我尝试了以下更改(以下git diff testcase_test.py
和python testcase_test.py
结果):
尝试1:
diff --git a/testcase_test.py b/testcase_test.py
index d6d6e59..ae274c8 100644
--- a/testcase_test.py
+++ b/testcase_test.py
@@ -3,9 +3,8 @@ import unittest.mock
class MainTest(unittest.TestCase):
- @unittest.mock.patch('testcase_module.ec2', spec_set=['instances'])
- def test_f(self, ec2_mock):
- ec2_mock.instances.spec_set = ['all']
+ @unittest.mock.patch('testcase_module.ec2', spec_set=['instances.all'])
+ def test_f(self, _):
testcase_module.f()
产地:
E
======================================================================
ERROR: test_f (__main__.MainTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3.5/unittest/mock.py", line 1157, in patched
return func(*args, **keywargs)
File "testcase_test.py", line 8, in test_f
testcase_module.f()
File "/path/to/project/testcase_module.py", line 8, in f
return ec2.instances.all()
File "/usr/lib/python3.5/unittest/mock.py", line 578, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'instances'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
尝试2:
diff --git a/testcase_test.py b/testcase_test.py
index d6d6e59..d93abd1 100644
--- a/testcase_test.py
+++ b/testcase_test.py
@@ -3,9 +3,8 @@ import unittest.mock
class MainTest(unittest.TestCase):
- @unittest.mock.patch('testcase_module.ec2', spec_set=['instances'])
- def test_f(self, ec2_mock):
- ec2_mock.instances.spec_set = ['all']
+ @unittest.mock.patch('testcase_module.ec2.instances', spec_set=['all'])
+ def test_f(self):
testcase_module.f()
产地:
E
======================================================================
ERROR: test_f (__main__.MainTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3.5/unittest/mock.py", line 1149, in patched
arg = patching.__enter__()
File "/usr/lib/python3.5/unittest/mock.py", line 1312, in __enter__
setattr(self.target, self.attribute, new_attr)
AttributeError: can't set attribute
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.5/unittest/mock.py", line 1170, in patched
patching.__exit__(*exc_info)
File "/usr/lib/python3.5/unittest/mock.py", line 1334, in __exit__
delattr(self.target, self.attribute)
AttributeError: can't delete attribute
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
如果调用了instances.all
之外的其他方法,怎么能让它失败?
答案 0 :(得分:0)
尝试使用mock_add_spec
。
ec2_mock.instances.mock_add_spec(['all'], spec_set=True)
链接:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.mock_add_spec
答案 1 :(得分:-1)
这样做是怎么回事:
@unittest.mock.patch('testcase_module.boto3.resource', autospec=True)
def test_f(self, ec2_resource_mock):
class InstanceStub(object):
def all(self):
return [...]
ec2_resource_mock.return_value = mock.create_autospec(
EC2InstanceType, instances=InstanceStub())
testcase_module.f()