在 flask-potion 中测试 409 冲突
Testing 409 conflict in flask-potion
我正在尝试测试如果存在具有相同 ID 的烧瓶药水的 ModelResource 在创建时会发生冲突:
class Device(db.Model):
__tablename__ = 'device'
uuid = db.Column(UUID, primary_key=True, default=lambda: str(uuid4()))
make = db.Column(db.String(150), nullable=False)
model = db.Column(db.String(150), nullable=False)
category = db.Column(db.String(150), nullable=False)
class DeviceResource(ModelResource):
class Meta:
model = Device
id_converter = 'string'
class Schema:
uuid = fields.UUID(io='wr')
测试是作为 pytest yield fixture 完成的:
@pytest.fixture(scope='session')
def application():
flask_app = create_app()
# return a webtest.TestApp
test_app = TestApp(flask_app)
test_app.current_app_context = flask_app.app_context
return test_app
@pytest.yield_fixture(scope='function')
def single_device(application):
obj = Device(**DEVICE_JSON)
with application.current_app_context():
db.session.add(obj)
db.session.commit()
yield obj
for device in Device.query.all():
db.session.delete(device)
db.session.commit()
def test_create_device_fail(single_device, application):
response = application.post_json('/api/v1/device', params=DEVICE_JSON, expect_errors=True)
assert response.status_code == 409
但是当我 运行 我得到以下错误:
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: New instance <Device at 0x7fb5e83d5d68> with identity key (<class 'complex_service.db.Device'>, ('1ec67df1-e673-4505-8e00-5be58ec1656a',)) conflicts with persistent instance <Device at 0x7fb5e84419e8>
连同
sqlalchemy.orm.exc.FlushError: New instance <Device at 0x7fb5e83d5d68> with identity key (<class 'complex_service.db.Device'>, ('1ec67df1-e673-4505-8e00-5be58ec1656a',)) conflicts with persistent instance <Device at 0x7fb5e84419e8>
即使我没有通过测试中的夹具而是做了一个双重请求,它也不起作用,失败并出现相同的错误
def test_create_device_fail(single_device, application):
application.post_json('/api/v1/device', params=DEVICE_JSON, expect_errors=True)
assert response.status_code == 200
response = application.post_json('/api/v1/device', params=DEVICE_JSON, expect_errors=True)
assert response.status_code == 409
知道如何解决吗?
多亏了@lyschoening 的建议,我才得以成功,
@pytest.yield_fixture(scope='function')
def single_device(application):
obj = Device(**DEVICE_JSON)
with application.current_app_context():
db.session.add(obj)
db.session.commit()
yield None
with application.current_app_context():
for device in Device.query.all():
db.session.delete(device)
db.session.commit()
所以基本上没有将对象交给测试并且有 2 个不同的应用程序上下文
我正在尝试测试如果存在具有相同 ID 的烧瓶药水的 ModelResource 在创建时会发生冲突:
class Device(db.Model):
__tablename__ = 'device'
uuid = db.Column(UUID, primary_key=True, default=lambda: str(uuid4()))
make = db.Column(db.String(150), nullable=False)
model = db.Column(db.String(150), nullable=False)
category = db.Column(db.String(150), nullable=False)
class DeviceResource(ModelResource):
class Meta:
model = Device
id_converter = 'string'
class Schema:
uuid = fields.UUID(io='wr')
测试是作为 pytest yield fixture 完成的:
@pytest.fixture(scope='session')
def application():
flask_app = create_app()
# return a webtest.TestApp
test_app = TestApp(flask_app)
test_app.current_app_context = flask_app.app_context
return test_app
@pytest.yield_fixture(scope='function')
def single_device(application):
obj = Device(**DEVICE_JSON)
with application.current_app_context():
db.session.add(obj)
db.session.commit()
yield obj
for device in Device.query.all():
db.session.delete(device)
db.session.commit()
def test_create_device_fail(single_device, application):
response = application.post_json('/api/v1/device', params=DEVICE_JSON, expect_errors=True)
assert response.status_code == 409
但是当我 运行 我得到以下错误:
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: New instance <Device at 0x7fb5e83d5d68> with identity key (<class 'complex_service.db.Device'>, ('1ec67df1-e673-4505-8e00-5be58ec1656a',)) conflicts with persistent instance <Device at 0x7fb5e84419e8>
连同
sqlalchemy.orm.exc.FlushError: New instance <Device at 0x7fb5e83d5d68> with identity key (<class 'complex_service.db.Device'>, ('1ec67df1-e673-4505-8e00-5be58ec1656a',)) conflicts with persistent instance <Device at 0x7fb5e84419e8>
即使我没有通过测试中的夹具而是做了一个双重请求,它也不起作用,失败并出现相同的错误
def test_create_device_fail(single_device, application):
application.post_json('/api/v1/device', params=DEVICE_JSON, expect_errors=True)
assert response.status_code == 200
response = application.post_json('/api/v1/device', params=DEVICE_JSON, expect_errors=True)
assert response.status_code == 409
知道如何解决吗?
多亏了@lyschoening 的建议,我才得以成功,
@pytest.yield_fixture(scope='function')
def single_device(application):
obj = Device(**DEVICE_JSON)
with application.current_app_context():
db.session.add(obj)
db.session.commit()
yield None
with application.current_app_context():
for device in Device.query.all():
db.session.delete(device)
db.session.commit()
所以基本上没有将对象交给测试并且有 2 个不同的应用程序上下文