Pio*_*r P 6 python mocking pytest boto3 moto
我想知道为什么mock_s3decorator在用作pytest fixture的装饰器时不起作用.test_with_fixture在提供与test_without灯具相同的代码时失败.嗯,"相同",因为它明确地装饰.
test_with_fixture引发AccessDenied错误,但S3错误的类型在这种情况下不相关.问题是,在使用fixture的测试中不会模拟client.list_objects.
pytest - 3.1.2
moto - 1.0.1
boto3 - 1.0.4
import pytest
import boto3
from moto import mock_s3
BUCKET = 'Foo'
@pytest.fixture()
@mock_s3
def moto_boto():
    res = boto3.resource('s3')
    res.create_bucket(Bucket=BUCKET)
def test_with_fixture(moto_boto):
    client = boto3.client('s3')
    client.list_objects(Bucket=BUCKET)
@mock_s3
def test_without_fixture():     
    res = boto3.resource('s3')
    res.create_bucket(Bucket=BUCKET)
    client = boto3.client('s3')
    client.list_objects(Bucket=BUCKET)
The problem of your fixture is that you are not using it later although it is in the signature of your test test_with_fixture(moto_boto). I suggest you to create a fixture that returns a function that can be instantiated within your test to create the mocked objects that your test requires (the s3 bucket). An example of such an implementation could be as follows:
import pytest
import boto3
from moto import mock_s3
BUCKET = 'Foo'
@pytest.fixture()
def moto_boto():
    @mock_s3
    def boto_resource():
        res = boto3.resource('s3')
        res.create_bucket(Bucket=BUCKET)
        return res
    return boto_resource
@mock_s3
def test_with_fixture(moto_boto):
        moto_boto()
        client = boto3.client('s3')
        client.list_objects(Bucket=BUCKET)
In this case I am using the moto library through a decorator in both the fixture and the test but the context manager could be similarly used as explained in the moto README
小智 5
一种替代方法是使用“自动使用”测试装置,在其中启动和停止moto服务器并创建测试桶。
这是基于mikegrima在https://github.com/spulec/moto/issues/620上的评论。
import pytest
import boto3
from moto import mock_s3
BUCKET = 'Foo'
@pytest.fixture(autouse=True)
def moto_boto():
    # setup: start moto server and create the bucket
    mock_s3().start()
    res = boto3.resource('s3')
    res.create_bucket(Bucket=BUCKET)
    yield
    # teardown: stop moto server
    mock_s3.stop()
def test_with_fixture():
    client = boto3.client('s3')
    client.list_objects(Bucket=BUCKET)
使用上下文管理器:
import pytest
import boto3
from moto import mock_s3
BUCKET = 'Foo'
@pytest.fixture()
def moto_boto():
    with mock_s3():
        res = boto3.resource('s3')
        res.create_bucket(Bucket=BUCKET)
        yield
def test_with_fixture(moto_boto):
    client = boto3.client('s3')
    client.list_objects(Bucket=BUCKET)
使用上下文管理器,start并stop在后台调用。