Тест pytest всегда возвращает abc.is_online True

Тест всегда возвращает abc.is_online True. Но abc.is_online должен быть False, потому что задача celery делает is_online False через 60 секунд после этого.. Ошибка Meassge: assert True == False где True = <ABC: Charles Reyes>.is_online

@app.task(name="task.abc_last_active") #Celery task
def abc_last_active():
    now = timezone.localtime()

    for xyz in ABC.objects.all():
        if not xyz.last_active:
            continue

        elapsed = now - xyz.last_active

        if elapsed.total_seconds() >= settings.ABC_TIMEOUT: #60 Sec
            xyz.is_online = False
            xyz.save()

@pytest.fixture
def create_abc():
    abc = ABC.objects.create(
        phone="123234432",
        location=Point(1, 4),
        last_active=timezone.localtime() - timezone.timedelta(seconds=162),
        is_online=True,
    )
    return abc

@pytest.mark.django_db
def test_inactive_abc_gets_deactivated(create_abc):
    print(create_abc.is_online, "before deactivation")

    abc_last_active()

    print(create_abc.is_online, "after deactivation")
    assert create_abc.is_online == False

Используйте create_abc.refresh_from_db() после запуска задачи Celery. Django не будет обращаться к базе данных тут и там при каждом изменении obj.

EDIT: Улучшите ответ, чтобы уточнить, что здесь происходит.

Вы создаете новый объект в памяти здесь (который теперь сохраняется в DB):

def create_abc():
    ...

затем задача celery берет объект DB и создает новый в памяти (старый create_abc в тестовом замыкании к этому моменту остается старым). После завершения задачи объект приспособления, находящийся в памяти , ничего не знает о новом в БД . Поэтому вы должны загрузить свежий экземпляр DB в ваш старый obj, вызвав refresh_from_db() на нем.

Для тестов я бы рекомендовал вместо обновления (потому что вы можете забыть обновить) создавать утверждения, которые явно используют свежие экземпляры, и выработать такую привычку, чтобы избежать проблем в будущем. Т.е.:

@pytest.mark.django_db
def test_inactive_abc_gets_deactivated(create_abc):
    ...
    assert ABC.objects.first().is_online == False

Вернуться на верх