2016-04-23 3 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.

Смежные вопросы