Moto 不适用于 python 单元测试 setUp() 调用
Moto does not work with python unit test setUp() call
我正在使用 moto 和 Python 3.7 来模拟一些 S3 交互。如果所有模拟代码都包含在测试方法中,则 moto 似乎可以正常工作。当我将一些初步代码移至 setUp()
时,测试失败,就好像 setUp()
从未 运行.
import unittest
import boto3
from moto import mock_s3
class BucketFacadeTests(unittest.TestCase):
@mock_s3
def setUp(self):
print('setUp called')
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
def do_test(self):
s3 = boto3.resource('s3', region_name='us-east-1')
the_object = s3.Object('bucket', 'a/b/c/d.txt')
string_data = the_object.get()['Body'].read().decode('utf-8')
self.assertEqual('my dog has fleas', string_data)
@mock_s3
def test_bucket_can_be_accessed_with_setup(self):
self.do_test()
@mock_s3
def test_bucket_can_be_accessed_without_setup(self):
# This does what setUp() should
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
self.do_test()
当我不依赖 setUp()
时,一切都 运行 符合预期
Testing started at 07:49 ...
/Users/paul/.virtualenvs/nui-converter/bin/python "/Applications/PyCharm CE.app/Contents/helpers/pycharm/_jb_unittest_runner.py" --target BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_without_setup
Launching unittests with arguments python -m unittest BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_without_setup in /Users/Paul/as/nui-converter/tests/InventoryLoader
setUp called
Ran 1 test in 0.103s
OK
Process finished with exit code 0
然而当我依赖setUp()
时它失败了
Testing started at 07:56 ...
/Users/paul/.virtualenvs/nui-converter/bin/python "/Applications/PyCharm CE.app/Contents/helpers/pycharm/_jb_unittest_runner.py" --target BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_with_setup
Launching unittests with arguments python -m unittest BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_with_setup in /Users/Paul/as/nui-converter/tests/InventoryLoader
setUp called
Ran 1 test in 0.183s
FAILED (errors=1)
Error
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
yield
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
testMethod()
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/moto/core/models.py", line 74, in wrapper
result = func(*args, **kwargs)
File "/Users/Paul/as/nui-converter/tests/InventoryLoader/BucketFacade2Tests.py", line 27, in test_bucket_can_be_accessed_with_setup
self.do_test()
File "/Users/Paul/as/nui-converter/tests/InventoryLoader/BucketFacade2Tests.py", line 22, in do_test
string_data = the_object.get()['Body'].read().decode('utf-8')
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/boto3/resources/factory.py", line 520, in do_action
response = action(self, *args, **kwargs)
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/boto3/resources/action.py", line 83, in __call__
response = getattr(parent.meta.client, operation_name)(**params)
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/botocore/client.py", line 661, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.errorfactory.NoSuchBucket: An error occurred (NoSuchBucket) when calling the GetObject operation: The specified bucket does not exist
Process finished with exit code 1
我是做错了什么,还是把 moto 推到了极限?
问题是您将 mock_s3 装饰器应用到 setUp()
方法并直接应用 test methods
。这会产生单独的模拟 s3 环境,因此不会共享在 setUp()
方法中完成的任何操作。
解决方案是将 @mock_s3
装饰器应用于整个 BucketFacadeTests
class。
下面的代码应该可以正常工作。
import unittest
import boto3
from moto import mock_s3
@mock_s3
class BucketFacadeTests(unittest.TestCase):
def setUp(self):
print('setUp called')
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
def do_test(self):
s3 = boto3.resource('s3', region_name='us-east-1')
the_object = s3.Object('bucket', 'a/b/c/d.txt')
string_data = the_object.get()['Body'].read().decode('utf-8')
self.assertEqual('my dog has fleas', string_data)
def test_bucket_can_be_accessed_with_setup(self):
self.do_test()
def test_bucket_can_be_accessed_without_setup(self):
# This does what setUp() should
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
self.do_test()
我正在使用 moto 和 Python 3.7 来模拟一些 S3 交互。如果所有模拟代码都包含在测试方法中,则 moto 似乎可以正常工作。当我将一些初步代码移至 setUp()
时,测试失败,就好像 setUp()
从未 运行.
import unittest
import boto3
from moto import mock_s3
class BucketFacadeTests(unittest.TestCase):
@mock_s3
def setUp(self):
print('setUp called')
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
def do_test(self):
s3 = boto3.resource('s3', region_name='us-east-1')
the_object = s3.Object('bucket', 'a/b/c/d.txt')
string_data = the_object.get()['Body'].read().decode('utf-8')
self.assertEqual('my dog has fleas', string_data)
@mock_s3
def test_bucket_can_be_accessed_with_setup(self):
self.do_test()
@mock_s3
def test_bucket_can_be_accessed_without_setup(self):
# This does what setUp() should
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
self.do_test()
当我不依赖 setUp()
时,一切都 运行 符合预期
Testing started at 07:49 ...
/Users/paul/.virtualenvs/nui-converter/bin/python "/Applications/PyCharm CE.app/Contents/helpers/pycharm/_jb_unittest_runner.py" --target BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_without_setup
Launching unittests with arguments python -m unittest BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_without_setup in /Users/Paul/as/nui-converter/tests/InventoryLoader
setUp called
Ran 1 test in 0.103s
OK
Process finished with exit code 0
然而当我依赖setUp()
Testing started at 07:56 ...
/Users/paul/.virtualenvs/nui-converter/bin/python "/Applications/PyCharm CE.app/Contents/helpers/pycharm/_jb_unittest_runner.py" --target BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_with_setup
Launching unittests with arguments python -m unittest BucketFacade2Tests.BucketFacadeTests.test_bucket_can_be_accessed_with_setup in /Users/Paul/as/nui-converter/tests/InventoryLoader
setUp called
Ran 1 test in 0.183s
FAILED (errors=1)
Error
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 59, in testPartExecutor
yield
File "/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/case.py", line 615, in run
testMethod()
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/moto/core/models.py", line 74, in wrapper
result = func(*args, **kwargs)
File "/Users/Paul/as/nui-converter/tests/InventoryLoader/BucketFacade2Tests.py", line 27, in test_bucket_can_be_accessed_with_setup
self.do_test()
File "/Users/Paul/as/nui-converter/tests/InventoryLoader/BucketFacade2Tests.py", line 22, in do_test
string_data = the_object.get()['Body'].read().decode('utf-8')
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/boto3/resources/factory.py", line 520, in do_action
response = action(self, *args, **kwargs)
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/boto3/resources/action.py", line 83, in __call__
response = getattr(parent.meta.client, operation_name)(**params)
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Users/paul/.virtualenvs/nui-converter/lib/python3.7/site-packages/botocore/client.py", line 661, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.errorfactory.NoSuchBucket: An error occurred (NoSuchBucket) when calling the GetObject operation: The specified bucket does not exist
Process finished with exit code 1
我是做错了什么,还是把 moto 推到了极限?
问题是您将 mock_s3 装饰器应用到 setUp()
方法并直接应用 test methods
。这会产生单独的模拟 s3 环境,因此不会共享在 setUp()
方法中完成的任何操作。
解决方案是将 @mock_s3
装饰器应用于整个 BucketFacadeTests
class。
下面的代码应该可以正常工作。
import unittest
import boto3
from moto import mock_s3
@mock_s3
class BucketFacadeTests(unittest.TestCase):
def setUp(self):
print('setUp called')
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
def do_test(self):
s3 = boto3.resource('s3', region_name='us-east-1')
the_object = s3.Object('bucket', 'a/b/c/d.txt')
string_data = the_object.get()['Body'].read().decode('utf-8')
self.assertEqual('my dog has fleas', string_data)
def test_bucket_can_be_accessed_with_setup(self):
self.do_test()
def test_bucket_can_be_accessed_without_setup(self):
# This does what setUp() should
s3 = boto3.resource('s3', region_name='us-east-1')
s3.create_bucket(Bucket='bucket')
key = 'a/b/c/d.txt'
object = s3.Object('bucket', key)
object.put(Body='my dog has fleas')
self.do_test()