问题
How do you pass exceptions that require arguments as mock side_effects?
I'm trying to test for assertRaises of boto.exception.EC2ResponsError, but get a "TypeError: init() takes at least 3 arguments (1 given)" in _mock_call.
@mock_ec2
@patch.object(Ec2Region, 'connect')
def test_ec2_get_raises(self, mock_connect):
conn = boto.connect_ec2()
mock_connect.return_value = conn
reservation = conn.run_instances('ami-1234abcd')
instance = reservation.instances[0]
Ec2Instance.objects.create(region=self.region, account=self.account,
instance_id=instance.id)
mock_connect.side_effect = boto.exception.EC2ResponseError
self.assertRaises(
boto.exception.EC2ResponseError,
Ec2Instance.ec2_get, self.account, self.region)
The error I'm getting is this:
======================================================================
ERROR: test_ec2_get_raises (session_ec2.tests.test_instance.Ec2InstanceTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/bschott/.virtualenvs/session-ec2/lib/python2.7/site-packages/moto/core/models.py", line 70, in wrapper
result = func(*args, **kwargs)
File "/Users/bschott/.virtualenvs/session-ec2/lib/python2.7/site-packages/mock.py", line 1201, in patched
return func(*args, **keywargs)
File "/Users/bschott/Source/session-ec2/session_ec2/tests/test_instance.py", line 84, in test_ec2_get_raises
Ec2Instance.ec2_get, self.account, self.region)
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 475, in assertRaises
callableObj(*args, **kwargs)
File "/Users/bschott/Source/session-ec2/session_ec2/models/instance.py", line 110, in ec2_get
connection = region.connect(account)
File "/Users/bschott/.virtualenvs/session-ec2/lib/python2.7/site-packages/mock.py", line 955, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/Users/bschott/.virtualenvs/session-ec2/lib/python2.7/site-packages/mock.py", line 1010, in _mock_call
raise effect
TypeError: __init__() takes at least 3 arguments (1 given)
回答1:
As documented in Calling section you can use both instance or class in side_effect
initialization. Moreover you can use a callable that raise your desired exception.
When class is used to define side_effect
and the desired exception has not the trivial empty constructor you will get an exception like the one you had because mock
framework doesn't know how to build that exception.
In your case you can use something like
mock_connect.side_effect = boto.exception.EC2ResponseError(400, "My reason", "my body")
来源:https://stackoverflow.com/questions/30677100/how-do-you-pass-exception-arguments-to-python-unittest-mock-side-effect