允许Ecto查询在测试环境中立即运行?

时间:2018-12-31 16:34:54

标签: elixir phoenix-framework ecto postgrex

我想编写测试来验证我的应用程序中的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 problem的风险,我愿意接受其他建议。谢谢!

2 个答案:

答案 0 :(得分:1)

由于似乎您正在尝试测试get_in_order_of_recency方法(而不是数据库/ 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"})

在测试中而不是使用create界面。这样一来,您就可以验证您的方法是否正确地按所需顺序检索了人员。

或者,将测试失败视为合法。同时引入多个记录时,不会保持您期望的顺序。作为解决方法,将id作为第二列添加,以降序排序,这将强制执行您要查找的顺序。

答案 1 :(得分:0)

您正在测试xyplot(v ~ i | g + h, df, type="l", scales=list(y=list(relation="free"))) 和您的SQL驱动程序。您不应该这样做,它意义为零。

您可能要在这里进行测试的唯一一件事(尽管我很肯定,这也是多余的),是填充了xyplot(v ~ i | g + h, df, type="l", scales=list(y=list(relation="sliced"))) 字段。

Ecto.Query.order_by/3有效;如果您不信任它,则最好使用其他一些库。