2016-04-23 99 views
0

我試圖用瓶測試一個瓶,SQLAlchemy的模型來檢驗。更確切地說,這個模型的一個靜態方法使用first_or_404(),我無法找到一種方法讓我的測試工作。瓶試驗和燒瓶的SQLAlchemy:first_or_404()

這裏,突出的問題一個自包含例如:

from flask import Flask 
from flask_sqlalchemy import SQLAlchemy 
from flask.ext.testing import TestCase 

db = SQLAlchemy() 

class ModelToTest(db.Model): 
    __tablename__ = 'model_to_test' 
    identifier = db.Column(db.String(80), unique=True, nullable=False, primary_key=True) 

    @staticmethod 
    def get_by_identifier(identifier): 
     return ModelToTest.query.filter_by(identifier=identifier).first_or_404() 

class Config: 
    DEBUG = True 
    TESTING = True 
    SQLALCHEMY_DATABASE_URI = 'sqlite:///' 
    SQLALCHEMY_TRACK_MODIFICATIONS = False 

class TestGetByIdentifier(TestCase): 

    def create_app(self): 
     app = Flask('test') 
     app.config.from_object(Config()) 
     db.init_app(app) 
     return app 

    def setUp(self): 
     db.create_all() 

    def tearDown(self): 
     db.session.remove() 
     db.drop_all() 

    def test_get_by_identifier(self): 
     self.assert404(ModelToTest.get_by_identifier('identifier')) 

我得到了錯誤:

(my_env) PS C:\Dev\Test\Python\test_flask> nosetests-3.4.exe 
E 
====================================================================== 
ERROR: test_get_by_identifier (test_flask.TestGetByIdentifier) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "C:\Dev\Test\Python\test_flask\test_flask.py", line 37, in test_get_by_identifier 
    self.assert404(ModelToTest.get_by_identifier('identifier')) 
    File "C:\Dev\Test\Python\test_flask\test_flask.py", line 13, in get_by_identifier 
    return ModelToTest.query.filter_by(identifier=identifier).first_or_404() 
    File "c:\\my_env\lib\site-packages\flask_sqlalchemy\__init__.py", line 431, in first_or_404 
    abort(404) 
    File "c:\\my_env\lib\site-packages\werkzeug\exceptions.py", line 646, in __call__ 
    raise self.mapping[code](*args, **kwargs) 
werkzeug.exceptions.NotFound: 404: Not Found 

---------------------------------------------------------------------- 
Ran 1 test in 0.913s 

所以行self.assert404(ModelToTest.get_by_identifier('identifier'))確實產生了first_or_404()調用一個例外,這個例外是werkzeug.exceptions.NotFound,它似乎不是self.assert404()預期的結果。

要求來運行這個測試是:

  • 燒瓶
  • 燒瓶SQLAlchemy的
  • 燒瓶測試

值得注意的是,當我使用的功能在應用它表現如預期。

在此先感謝。

+0

有沒有列在那裏'ID = id'監守你沒有塞入任何東西,所以你得到一個404這似乎完全符合預期。 – davidism

+0

@davidism對不起,我採取了錯誤的例子。修正了與匹配錯誤的示例。 – Johan

回答

1

我引用我已經在GitHub上得到的回答:

https://github.com/jarus/flask-testing/issues/89

I believe this is a misunderstanding about the way to drive the test. The first_or_404 function will indeed raise a NotFound exception. When in the context of the request, the exception will bubble up, be handled, and turn into a 404 http response, which is what flask-testing is looking for.

However, you are not in the context of a request in this case since you are calling the method directly and it is simply resulting in an exception. You could do this to make the test work

from werkzeug.exceptions import NotFound 

def test_get_by_identifier(self): 
    with self.assertRaises(NotFound): 
     ModelToTest.get_by_identifier('identifier') 

Or, you can stick that function behind a route and test it using self.client which will correctly give you a 404 http response. However, testing the exception (without the use of flask-testing) may be more appropriate in this case given the level you are testing at.