pytest 测试总是 return abc.is_online True

The pytest test always return abc.is_online True

测试总是returnabc.is_online正确。但是 abc.is_online 应该是 False 因为 celery 任务在 60 秒后使 is_online False。 错误信息:断言 True == False 其中 True = .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

在 运行 那个 Celery 任务之后使用 create_abc.refresh_from_db()。每次更改 obj 时,Django 都不会到处访问数据库。

编辑:改进答案以澄清这里发生的事情。

您在此处的内存中创建一个新对象(现在保存到数据库):

def create_abc():
    ...

然后一个 celery 任务获取 DB 对象并在内存中创建一个新的(旧的 create_abc到那时,测试关闭仍然很旧)。 任务完成后,内存内存中的夹具对象对数据库中的新一无所知。因此,您必须通过调用 refresh_from_db() 将新的数据库实例加载到旧的 obj。

对于测试,我建议不要刷新(因为您可能会忘记刷新)创建显式使用新实例的断言,并养成这样的习惯以避免将来出现问题。即:

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