【问题标题】:Moto does not work with python unit test setUp() callMoto 不适用于 python 单元测试 setUp() 调用
【发布时间】:2018-12-27 13:00:38
【问题描述】:

我正在使用 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 超出了极限?

【问题讨论】:

    标签: amazon-web-services boto3 moto


    【解决方案1】:

    问题是您将 mock_s3 装饰器直接应用于setUp() 方法和test methods。这会产生单独的模拟 s3 环境,因此不会共享在 setUp() 方法中所做的任何事情。

    解决方案是将@mock_s3 装饰器应用于整个BucketFacadeTests 类。

    下面的代码应该可以按预期工作。

    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()
    

    【讨论】:

    • 非常感谢分享这个。它为我创造了奇迹。
    猜你喜欢
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 2011-03-04
    • 2016-03-22
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多