Estoy tratando de simular algunas llamadas a s3 en mi código python y me encuentro con algún tipo de error cuando se ejecuta mi prueba de unidad. A continuación se muestra el código donde invoco el módulo boto para llegar a S3. Estoy tratando de simular todas las llamadas a S3 en este código.
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)En mi código de prueba de unidad, tengo:
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)Sin embargo, me encuentro con este error cuando ejecuto mi prueba unitaria:
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¿Alguna idea de lo que me estoy perdiendo aquí? ¿Supongo que la burla sería sencilla como la que tengo en mi código?
El problema es que está llamando al boto real en su caso de prueba, no a su simulacro.
Debe simular el objeto usando el mismo nombre de símbolo que tiene dentro de su módulo de prueba. En lugar de intentar parchear 'boto.s3.connection.S3Connection', desea parchear 'test_s3.S3Connection'. Comienza con 'test_s3' porque ese es el nombre del módulo desde donde está cargando el código bajo prueba. Luego, después del punto, usa el mismo símbolo que dentro de ese módulo te da acceso a S3Connection (es decir, sin boto.s3.connection).
Además, el parche crea un simulacro automáticamente para usted, por lo que no necesita crear el primer objeto simulado. Y como ya parcheó S3Connection, en lugar de parchear cosas dentro de él, solo necesita conectar sus simulacros creados como valores de retorno para los métodos adecuados:
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)