0

Having issues writing a unit test for S3 client, it seems the test is trying to use a real s3 client rather than the one i have created for the test here is my example

    @pytest.fixture(autouse=True)
    def moto_boto(self):
        # setup: start moto server and create the bucket
        mocks3 = mock_s3()
        mocks3.start()
        res = boto3.resource('s3')
        bucket_name: str = f"{os.environ['BUCKET_NAME']}"
        res.create_bucket(Bucket=bucket_name)
        yield
        # teardown: stop moto server
        mocks3.stop()

    def test_with_fixture(self):
        from functions.s3_upload_worker import (
            save_email_in_bucket,
        )
        client = boto3.client('s3')
        bucket_name: str = f"{os.environ['BUCKET_NAME']}"
        client.list_objects(Bucket=bucket_name)
      
        save_email_in_bucket(
                "123AZT",
                os.environ["BUCKET_FOLDER_NAME"],
                email_byte_code,
            )

This results in the following error

botocore.exceptions.ClientError: An error occurred (ExpiredToken) when calling the PutObject operation: The provided token has expired.

code i am testing looks like this

def save_email_in_bucket(message_id, bucket_folder_name, body):
    s3_key = "".join([bucket_folder_name, "/", str(message_id), ".json"])
    s3_client.put_object(
        Bucket=bucket,
        Key=s3_key,
        Body=json.dumps(body),
        ContentType="application-json",
    )
    LOGGER.info(
        f"Saved email with messsage ID {message_id} in bucket folder {bucket_folder_name}"
    )
AnonymousAlias
  • 1,149
  • 2
  • 27
  • 68

1 Answers1

1

Not accepting this an an answer but useful for anyone who ends up here, I found a workaround where if I create the s3 client in the function i am trying to test then this approach will work rather than create it globally. I would prefer to find an actual solution though.

AnonymousAlias
  • 1,149
  • 2
  • 27
  • 68
  • 1
    The alternative is to import the module you're testing inside the test function. In both cases, the boto3-client is created after the mock is established, which is a requirement for moto to work. See https://github.com/spulec/moto/blob/master/README.md#what-about-those-pesky-imports – Bert Blommers Mar 27 '21 at 08:19