Разрешить выполнение запросов Ecto немедленно в тестовой среде?

Я хотел бы написать тесты для проверки того, что запросы SQL в моем приложении возвращают данные, соответствующие определенным ограничениям: а именно, что возвращаемые значения представлены в порядке убывания вставки. В приложении я использую timestamps() в моих схемах включить inserted_at поле к БД, и запросы к нему в моих запросах (SELECT … ORDER BY inserted_at DESC).

Моя проблема возникает в моих тестах: если у меня есть тестовый код, как

person1_params = %{name: "Tidehunter"}
{:ok, tidehunter} = People.create_person(person1_params)

person2_params = %{name: "Kunkka"}
{:ok, kunkka} = People.create_person(person2_params)

person3_params = %{name: "Windrunner"}
{:ok, windrunner} = People.create_person(person3_params)

и я хотел бы отстаивать их порядок, как

people = People.get_in_order_of_recency()
assert Enum.at(people, 0).name == "Windrunner"

это терпит неудачу, хотя в ручных тестах все это, кажется, работает. При осмотре я вижу, что inserted_at для всех трех записей одинаково. Я пытался добавить :timer.sleep() звонки, но это не меняет результат, предлагая некоторую группировку или лень на уровне Ecto/Postgrex.

"Самое простое" решение, о котором я мог подумать, - это какой-то способ "заставить" транзакцию произойти на месте вызова, чтобы я мог :timer.sleep(1) между ними, давая мне отчетливый inserted_at поля (таким образом, название вопроса), но рискуя проблемой XY, я открыт для других предложений. Спасибо!

2 ответа

Решение

Поскольку кажется, что вы пытаетесь протестировать метод get_in_order_of_recency, а не функции datetime вашей базы данных / ecto, вы можете использовать псевдоним <MYPROJ>.Repo а затем сделать что-то вроде:

Repo.insert!(%People{inserted_at: ~N[2019-01-01 00:00:10], name: "Tidehunter"})
Repo.insert!(%People{inserted_at: ~N[2019-01-01 00:00:11], name: "Kunkka"})
Repo.insert!(%People{inserted_at: ~N[2019-01-01 00:00:12], name: "Windrunner"})

В вашем тесте вместо использования интерфейса создания. Что позволит вам убедиться, что ваш метод правильно извлекает людей в нужном вам порядке.

В качестве альтернативы, сочтите тестовый сбой законным. Ваш желаемый порядок не сохраняется, когда несколько записей вводятся одновременно. В качестве исправления добавьте идентификатор в качестве второго столбца для упорядочения в порядке убывания, что обеспечит соблюдение порядка, который вы ищете.

Вы тестируете Ecto и ваш драйвер SQL. Вы не должны этого делать, это бессмысленно.

Единственное, что вы можете проверить здесь (хотя я уверен, что это также избыточно), это то, что inserted_at поле заполняется.

Ecto.Query.order_by/3 работает; если вы не доверяете этому, вам лучше использовать какую-нибудь другую библиотеку.

Другие вопросы по тегам