如何模拟或测试celery任务自定义更新

时间:2019-05-22 08:35:30

标签: python flask celery pytest celery-task

芹菜用于连接瓶中。芹菜工人很偏僻。芹菜任务中有更新状态。如何在单元测试中模拟自定义任务状态。 截至目前,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

0 个答案:

没有答案