Issue with Moto and creating pytest fixture

Hello

I have been trying to create a pytest fixture for s3 that contains a bucket that is created in the fixture.

@pytest.fixture
@mock_s3
def s3_hook():

    result = sut.S3Hook()
    result.location = 'test_location'

    result.connection = boto3.client('s3')
    result.connection.create_bucket(Bucket=result.location)
    return result

My test looks like this:

@mock_s3
def test_check_existing_file(s3_hook):

    saved_string = "Just writing some tests."

    s3_hook.connection.put_object(Bucket=s3_hook.location,
                                  Key='test_file',
                                  Body=saved_string)

    assert s3_hook.check_for_file('test_file') 

This fails with the message

<Message>The specified bucket does not exist</Message>

If I update the test to create the bucket at the start of the test the test starts passing.

s3_hook.connection.create_bucket(Bucket=s3_hook.location)

Any thoughts on this?

I am using: pytest==2.8.0 moto==0.4.24

Thanks

Asked Nov 21 '21 09:11
avatar limbosongs
limbosongs

4 Answer:

For pytest, I've had success making a fixture like this:

@pytest.yield_fixture(scope="function")
def s3_fixture():
    mock_s3().start()

    client = boto3.client("s3")
    resource = boto3.resource("s3")

    yield client, resource

    mock_s3().stop()

And then just using the fixture in my tests:

def test_s3_thing(s3_fixture):
    client = s3_fixture[0]
    client.create_bucket(Bucket="some-test-bucket")

You don't want to mock_s3() again before your test.

1
Answered Jun 07 '16 at 16:37
avatar  of mikegrima
mikegrima

I've had success making a fixture like this

Me too. You know, I feel like you just deprecated pytest-moto with that!

1
Answered Jun 22 '16 at 14:11
avatar  of decentral1se
decentral1se

Using a context manager:

@pytest.yield_fixture(scope="function")
def s3_fixture():
    with mock_s3():
        client = boto3.client("s3")
        resource = boto3.resource("s3")

        yield client, resource
1
Answered Apr 14 '20 at 13:49
avatar  of Perados
Perados

Fixing double instantiation of mock_s3() in @mikegrima's above comment (breaks in latest version of moto) referenced here: https://github.com/spulec/moto/issues/2559

@pytest.yield_fixture(scope="function")
def s3_fixture():
    mocks3 = mock_s3()
    mocks3.start()

    client = boto3.client("s3")
    resource = boto3.resource("s3")

    yield client, resource

    mocks3.stop()
1
Answered Dec 15 '19 at 19:33
avatar  of fuhrysteve
fuhrysteve