【问题标题】:Testing random value collisions in Elixir在 Elixir 中测试随机值冲突
【发布时间】:2017-08-16 01:18:51
【问题描述】:

我正在尝试创建一个测试用例来可靠地处理数据库中的值发生冲突的情况。当用户在我的应用程序中执行某些操作时,一个随机的 12 位数字会保存到附加到该操作的数据库中。如果数字不是全长,则将其填充为 12 位数字。如果数据库中已经存在该数字,则程序会选择另一个随机数字。

这听起来可能很愚蠢,但预期的用户群可能会少于 100-1000 个用户。

我的代码看起来像

def gen_random_unique() do
  unique = (:rand.uniform(1_000_000_000_000) - 1)
  |> Integer.to_string()
  |> String.pad_leading(12, ["0"])

  case get_from_database(unique) do
    nil ->
      unique
    _ ->
      gen_random_unique()
  end
end

除了测试第二个条件数百万次直到它通过之外,Elixir 中是否有更简单的方法来强制执行该路径?由于该函数是递归的,我不确定如何仅在第一次调用时模拟它(如果这是我需要采取的路径。)

谢谢!

【问题讨论】:

  • 您可以使用默认值 1_000_000_000_000 将 limit 作为函数的参数,并在测试中传递一个较小的值,例如100.
  • 为什么不在数据库级别设置唯一约束,如果已经存在就会报错?您还可以在数据库中编写一个函数,从而完全避免在应用程序中生成和检查值。您是否有任何理由不使用 UUID 而不是随机生成的数字?
  • 我会使用 UUID,但它是用户可以键入以查看记录的字符串。我也在想我可以让生成过程更具确定性,但仍然是 12 个字符。显然,UUID 将是创建用户类型的相当大的负担。 :P

标签: elixir


【解决方案1】:

看起来您正在使用覆盖率进行单元测试。

为什么不使用 get_from_database 的不同模拟进行 2 个单独的测试,以便您可以同时测试 case 分支。

【讨论】:

  • 这绝对是一个选择。我或多或少仍然是 Elixir 的“菜鸟”。是否可以在不连续运行测试的情况下进行测试?看起来模拟库搞砸了异步测试。
  • @DylanAspden 我想你可能在谈论this?如果您确实需要并行不同的测试,您可以制作单独的测试用例。
  • 我重新考虑了整个事情,最终选择让流程更具确定性。谢谢!
猜你喜欢
  • 2013-02-25
  • 2017-01-08
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 2020-04-12
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
相关资源
最近更新 更多