我想编写测试来验证我的应用程序中的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的风险,我愿意接受其他建议。谢谢!
答案 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
有效;如果您不信任它,则最好使用其他一些库。