diff --git a/docs/docs/contributing/new_feature.rst b/docs/docs/contributing/new_feature.rst index 1cc5c8851..6caf102d3 100644 --- a/docs/docs/contributing/new_feature.rst +++ b/docs/docs/contributing/new_feature.rst @@ -9,6 +9,7 @@ Moto has a script that can automatically provide the scaffolding for a new servi Please try it out by running: .. sourcecode:: bash + export AWS_DEFAULT_REGION="us-east-2" python scripts/scaffold.py diff --git a/docs/docs/faq.rst b/docs/docs/faq.rst index 547956dea..866d88aea 100644 --- a/docs/docs/faq.rst +++ b/docs/docs/faq.rst @@ -20,7 +20,7 @@ Moto has a dependency on the pip-module `cryptography`. As of Cryptography >= 3. Most OS/platforms will support the installation of Rust, but if you're getting any errors related to this, see the cryptography documentation for more information: https://cryptography.io/en/latest/installation/#rust Can I mock the default AWS region? -######################### +################################### By default, Moto only allows valid regions, supporting the same regions that AWS supports. diff --git a/docs/docs/getting_started.rst b/docs/docs/getting_started.rst index 2b1974ee1..f47f6d9d0 100644 --- a/docs/docs/getting_started.rst +++ b/docs/docs/getting_started.rst @@ -184,6 +184,8 @@ The decorator is effective for every test-method inside your class. State is not # 'bucket_inside' however, created inside the other test, no longer exists pass +.. note:: A tearDown-method can be used to destroy any buckets/state, but because state is automatically destroyed before a test-method start, this is not strictly necessary. + Stand-alone server mode ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/moto/core/models.py b/moto/core/models.py index 9a54dd5ed..8cb0f65fb 100644 --- a/moto/core/models.py +++ b/moto/core/models.py @@ -127,16 +127,21 @@ class BaseMockAWS: return wrapper def decorate_class(self, klass): - direct_methods = set( - x - for x, y in klass.__dict__.items() - if isinstance(y, (FunctionType, classmethod, staticmethod)) - ) + direct_methods = get_direct_methods_of(klass) defined_classes = set( x for x, y in klass.__dict__.items() if inspect.isclass(y) ) - has_setup_method = "setUp" in direct_methods + # Get a list of all userdefined superclasses + superclasses = [ + c for c in klass.__mro__ if c not in [unittest.TestCase, object] + ] + # Get a list of all userdefined methods + supermethods = itertools.chain( + *[get_direct_methods_of(c) for c in superclasses] + ) + # Check whether the user has overridden the setUp-method + has_setup_method = "setUp" in supermethods for attr in itertools.chain(direct_methods, defined_classes): if attr.startswith("_"): @@ -200,6 +205,14 @@ class BaseMockAWS: del os.environ[k] +def get_direct_methods_of(klass): + return set( + x + for x, y in klass.__dict__.items() + if isinstance(y, (FunctionType, classmethod, staticmethod)) + ) + + RESPONSES_METHODS = [ responses.GET, responses.DELETE, diff --git a/tests/test_core/test_decorator_calls.py b/tests/test_core/test_decorator_calls.py index a614efead..8b26f53d7 100644 --- a/tests/test_core/test_decorator_calls.py +++ b/tests/test_core/test_decorator_calls.py @@ -159,6 +159,26 @@ class TestWithPseudoPrivateMethod(unittest.TestCase): s3.head_bucket(Bucket="mybucket") +@mock_s3 +class Baseclass(unittest.TestCase): + def setUp(self): + self.s3 = boto3.resource("s3", region_name="us-east-1") + self.client = boto3.client("s3", region_name="us-east-1") + self.test_bucket = self.s3.Bucket("testbucket") + self.test_bucket.create() + + def tearDown(self): + # The bucket will still exist at this point + self.test_bucket.delete() + + +@mock_s3 +class TestSetUpInBaseClass(Baseclass): + def test_a_thing(self): + # Verify that we can 'see' the setUp-method in the parent class + self.client.head_bucket(Bucket="testbucket").shouldnt.equal(None) + + @mock_s3 class TestWithNestedClasses: class NestedClass(unittest.TestCase):