我想知道为什么mock_s3
装饰器在用作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)
答案 0 :(得分:4)
你的灯具的问题在于你以后没有使用它,虽然它是你的测试test_with_fixture(moto_boto)
的签名。我建议你创建一个fixture,它返回一个可以在你的测试中实例化的函数,以创建你的测试所需的模拟对象(s3存储桶)。这种实现的一个例子如下:
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)
在这种情况下,我在夹具和测试中通过装饰器使用moto库,但是上下文管理器可以按照moto README
中的说明进行类似的使用答案 1 :(得分:4)
另一种方法是使用' autouse'测试夹具,您可以在其中启动和停止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)
答案 2 :(得分:1)
使用上下文管理器:
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
。