2016-04-25 143 views
0

我試圖測試瓶藥水衝突對創建ModelResource如果具有相同ID的一個存在:測試409衝突燒瓶藥水

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完成產量夾具:

@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> 

W一起第i個

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 

如何任何想法修理它?

+0

不知道到底怎麼pytest的作品,但它似乎在'single_device()'中添加了設備,然後在'yield'輸入了測試?您應該在放棄之前離開應用上下文,然後再次輸入以在測試後刪除設備。 – lyschoening

+0

使夾具這樣的: '@ pytest.yield_fixture(範圍= '功能') DEF single_device(應用): OBJ =設備(** DEVICE_JSON) 與application.current_app_context(): db.session。添加(OBJ) db.session.commit() 收率OBJ 與application.current_app_context(): 用於設備在Device.query.all(): db.session.delete(裝置) db.session.commit ()' 我收到一個新錯誤: 'sqlalchemy.orm.exc.DetachedInstanceError:Instance is not b回到會議;屬性刷新操作無法進行 – shipperizer

回答

0

感謝@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個不同的應用程序上下文