允许 Ecto 在测试环境中立即查询 运行?
Allow Ecto queries to run immediately in a test environment?
我想编写测试来验证我的应用程序 return 数据中的 SQL 查询是否遵守某些约束:即 return 值以降序插入的形式呈现命令。在应用程序中,我在我的模式中使用 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 层有一些批处理或惰性。
我能想到的 "simplest" 解决方案是 "force" 在呼叫站点发生交易的某种方式,因此我可以 :timer.sleep(1)
在它们之间,让我与众不同 inserted_at
字段(因此是问题标题),但冒着 XY problem 的风险,我愿意接受其他建议。谢谢!
由于您似乎正在尝试测试 get_in_order_of_recency 方法而不是 database/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"})
在您的测试中而不是使用创建界面。这将允许您验证您的方法是否正确地按照您想要的顺序检索人员。
作为替代方案,考虑测试失败是合理的。当同时引入多个记录时,您想要的顺序不会得到维护。作为补救措施,将 id 添加为第二列以按降序排序,这将强制执行您正在查找的顺序。
您正在测试 Ecto
和您的 SQL 驱动程序。你不应该那样做,这毫无意义。
您可能想要在这里测试的唯一一件事(虽然我肯定它也是多余的)是 inserted_at
字段被填充。
Ecto.Query.order_by/3
有效;如果你不信任它,你最好使用其他库。
我想编写测试来验证我的应用程序 return 数据中的 SQL 查询是否遵守某些约束:即 return 值以降序插入的形式呈现命令。在应用程序中,我在我的模式中使用 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 层有一些批处理或惰性。
我能想到的 "simplest" 解决方案是 "force" 在呼叫站点发生交易的某种方式,因此我可以 :timer.sleep(1)
在它们之间,让我与众不同 inserted_at
字段(因此是问题标题),但冒着 XY problem 的风险,我愿意接受其他建议。谢谢!
由于您似乎正在尝试测试 get_in_order_of_recency 方法而不是 database/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"})
在您的测试中而不是使用创建界面。这将允许您验证您的方法是否正确地按照您想要的顺序检索人员。
作为替代方案,考虑测试失败是合理的。当同时引入多个记录时,您想要的顺序不会得到维护。作为补救措施,将 id 添加为第二列以按降序排序,这将强制执行您正在查找的顺序。
您正在测试 Ecto
和您的 SQL 驱动程序。你不应该那样做,这毫无意义。
您可能想要在这里测试的唯一一件事(虽然我肯定它也是多余的)是 inserted_at
字段被填充。
Ecto.Query.order_by/3
有效;如果你不信任它,你最好使用其他库。