2017-08-16 88 views
1

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

这可能听起来很愚蠢,但预期的用户群可能会少于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 

除了测试次数的第二个条件上百万,直到它通过,有没有灵药更简单的方法,迫使这条道路?由于函数是递归的,我不知道我只能在第一次调用时如何模拟它(如果这是我需要采取的路径)。

谢谢!

+0

您可以将限制作为默认值为“1_000_000_000_000”的函数的参数,并在测试中将其传递给一个较小的值,例如, '100'。 – Dogbert

+0

为什么不在数据库级别只有一个唯一的约束,并且如果它已经存在就会报错?你也可以在数据库中编写一个函数,完全避免需要生成和检查应用程序中的值。是否有任何理由不只是使用UUID而不是随机生成的数字? –

+0

我会使用UUID,但它是用户可以键入以查看记录的字符串。我也在想我可以让这个世代过程更具决定性,但仍然有12个字符。很显然,UUID会成为用户类型的负担。 :P –

回答

1

看起来你正在进行覆盖面单元测试。

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

+0

这绝对是一种选择。我仍然是一个药剂“noob”或多或少。是否可以在没有连续运行测试的情况下进行测试?它看起来像模拟库混淆了异步测试。 –

+1

@DylanAspden我想你可能会说[this](https://github.com/elixir-lang/elixir/issues/3580)?如果你真的需要平行不同的测试,你可以做出不同的测试用例。 –

+0

我重新思考了整个事情,最终选择了让这个过程更具确定性。谢谢! –