我试图在python代码中模拟一些对s3的调用,但在单元测试运行时遇到了某种错误。下面是我调用boto模块以访问S3的代码。我试图在这段代码中模拟出所有对S3的调用。
from boto.s3.connection import S3Connection
s3_conn = S3Connection()
bucket_obj = s3_conn.get_bucket(bucket)
key = bucket_obj.lookup(path)
return int(key.size)
在我的单元测试代码中,我有:
mock_conn = mock.Mock()
mock_bucket = mock.Mock()
mock_key = mock.Mock()
with mock.patch('boto.s3.connection.S3Connection',
mock.Mock(return_value=mock_conn)):
with mock.patch('boto.s3.connection.S3Connection.get_bucket',
mock.Mock(return_value=mock_bucket)):
with mock.patch('boto.s3.connection.S3Connection.get_bucket.lookup',
mock.Mock(return_value=mock_key)):
mock_key.size.return_value = 50000
self.assertEquals(fake.check_size(),
50)
然而,当我运行我的单元测试时,我遇到了这个错误:
Traceback (most recent call last):
File "/home/vagrant/code/my-project/tests/test_loadfirmware.py", line 92, in test_check_size
self.assertEquals(fake.check_size(),
File "/home/vagrant/code/my-project/test_s3.py", line 80, in check_size
bucket_obj = s3_conn.get_bucket(bucket)
File "/home/vagrant/code/my-project/venv/local/lib/python2.7/site-packages/boto/s3/connection.py", line 506, in get_bucket
return self.head_bucket(bucket_name, headers=headers)
File "/home/vagrant/code/my-project/venv/local/lib/python2.7/site-packages/boto/s3/connection.py", line 525, in head_bucket
response = self.make_request('HEAD', bucket_name, headers=headers)
File "/home/vagrant/code/my-project/venv/local/lib/python2.7/site-packages/boto/s3/connection.py", line 664, in make_request
return super(S3Connection, self).make_request(
TypeError: must be type, not Mock
你知道我错过了什么吗?我会假设模仿会像我在代码中一样简单?
发布于 2017-03-08 01:18:59
问题是,您在测试用例中调用的是真正的boto,而不是mock。
您需要使用与其在测试模块中相同的符号名称来模拟对象。与其尝试修补'boto.s3.connection.S3Connection',不如修补'test_s3.S3Connection‘。它以“test_s3”开头,因为这是您从中加载测试代码的模块的名称。然后,在点之后,使用与该模块内的符号相同的符号来访问S3Connection (即,不使用boto.s3.connection)。
此外,patch会自动为您创建一个mock,因此您不需要创建第一个mock对象。由于您已经修补了S3Connection,而不是修补它内部的东西,您只需要插入您创建的模拟作为适当方法的返回值:
mock_bucket = mock.Mock()
mock_key = mock.Mock()
with mock.patch('test_s3.S3Connection') as mock_conn:
mock_conn.get_bucket.return_value = mock_bucket
mock_bucket.lookup.return_value = mock_key
mock_key.size.return_value = 50000
self.assertEquals(fake.check_size(), 50)
https://stackoverflow.com/questions/42657741
复制