芹菜用于连接瓶中。芹菜工人很偏僻。芹菜任务中有更新状态。如何在单元测试中模拟自定义任务状态。 截至目前,celery经纪人是Rabbit mq,celery后端是数据库sqlite,但最终将迁移到postgresql。
app_file.py
from .base import database_init, create_db
def create_app(**kwargs):
""" To setup Flask app """
connexion_app = create_connexion()
flask_app = connexion_app.app
load_config(flask_app)
database_init(flask_app)
create_db()
cache.init_app(flask_app, flask_app.config)
if kwargs.get('celery'):
init_celery(kwargs.get('celery'), flask_app)
init_app(connexion_app)
CORS(flask_app)
return flask_app
def create_connexion():
options = {"swagger_path": "../swagger/dist"}
connexion_app = connexion.App(
__name__, specification_dir='swaggers/',
options=options)
return connexion_app
app = create_app(celery=celery)
该数据库存在于base.py
中base.py
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = SQLAlchemy()
def database_init(application):
"""Initialize the db."""
# application.app_context().push()
db.init_app(application)
Migrate(application, db)
def create_db():
"""just a function which create the database according
to classes imported"""
db.create_all()
在api层
apis/fs.py
def create_fs_api(data):
"""Creates the fs"""
tasks = FSService.createFS.apply_async(
kwargs={'availability_zone': data['availability_zone'], 'description': data['description'],
'protocol': data['protocol'], 'network': data['network'], 'size': data['size'],
'user_id': user_id, 'account_id': account_id})
return jsonify({'jobId': tasks.id}), 201, \
{'Location': url_for('/fs/v0.apis_Fs_controllers_jobs_get_job_id',
job_id=tasks.id, _external=True)}
在资源文件中,在单元测试中,update_state无法模拟。这里没有给出整个业务逻辑。
controllers/Fs_service.py
class FSService:
@celery.task(bind=True)
def createFS(self, availability_zone, description, protocol, network, size, user_id, account_id):
"""Creates the fsystem"""
current = 0
count = 1
sleep_time = size
for i in range(count):
time.sleep(sleep_time)
fsId = get_uuid()
current += 1
self.update_state(state='PROGRESS',
meta={'current': i, 'total': count})
region = get_region(availability_zone)
data = {'fs_Id': fsId,
'status': 'ready',
'size': size,
'created': datetime.datetime.utcnow(),
'modified': datetime.datetime.utcnow()}
FOperations.create_fs(data)
time.sleep(20)
return {'fsId': [fsId, ], 'count': count, 'status': 'Fs Created Successfully',
'current': current, 'total': count, 'type': 'Fs'}
在conftest.py中,如何模拟create_db
@pytest.yield_fixture(scope='session')
def flask_app():
""" Setup Flask app for Testing """
with patch.object(app_file, 'celery') as celery_mock:
app = app_file.create_app(celery=celery_mock)
with app.app_context():
yield app
@pytest.fixture(scope='session')
def flask_app_client(flask_app):
""" Load up Flask app api client for testing """
flask_app.response_class = JSONResponse
return flask_app.test_client()
在单元测试中
test_fs_service.py
@pytest.mark.celery(result_backend='redis://')
class TestFS:
def test_createfs(self, mocker):
uuid = mocker.patch('apis.Fs.resources.fs_service.get_uuid')
uuid.return_value = 'cf905c4f-122f-4b36-8441-7efff26aa6bf'
mocker.patch('apis.Fs.resources.fs_service.time.sleep')
mocker.patch('apis.Fs.resources.fs_service.FOperations.create_fs')
res = FSService.createFS("us", "fs for clb", "nfsv4", "l1", 3,
'13434', 'fcd4f7f1-7bf2-4409-9a25-de9edf0a7747')
assert res == {'fSId': ['cf905c4f-122f-4b36-8441-7efff26aa6bf', ], 'count': 1,
'status': 'FS Created Successfully', 'current': 1, 'total': 1, 'type': 'FS'}
预期结果=>测试用例必须通过
实际结果 pytest -c setup.cfg tests / test_fs_service.py
错误是
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file (Background on this error at: http://sqlalche.me/e/e3q8)
__init__.py 58 WARNING Failed operation _store_result. Retrying 0 more times.
Traceback (most recent call last):
如何在fs_service.py中模拟self.update 如何在conftest.py中模拟db.create_all或create_db