Elixir:配置一个混合项目,始终将江湖骗子打印为列表



在测试我的Phoenix应用程序时,我经常遇到比较预期和实际记录ID列表的情况。错误解释起来很乏味,因为Elixir一直以骗子的身份打印整数列表,所以我的测试输出看起来像:

Assertion with == failed
code:  assert H.sort(Enum.map(list1, &(&1.id()))) == H.sort(Enum.map(list2, &(&1.id())))
left:  'stu'
right: 'st'

这促使我重写测试,以避免比较整数列表,这是可以容忍的,但在这样的语言中,耸耸肩并寻找变通方法是很遗憾的。所以我想知道是否有一种方法可以告诉Elixir/Mix,总是将整数列表打印为列表,而不是charlists/charstring。我写的是Ruby风格的Elixir,我几乎从不利用江湖骗子,对我来说,他们大多是一个棘手的问题。

多亏了这个答案,我知道有一种方法可以将IEx配置为始终将整数列表打印为列表。有没有一种方法可以在Mix中做到这一点,或者在Elixir本身的全球范围内做到,所以mix test会采用这种行为?

;人性化";江湖骗子可能是《长生不老药》中最令人困惑的陷阱之一。正如@Aleksei所指出的,这在ExUnit中是不可配置的(尽管您可以通过在.iex.exs文件中添加IEx.configure(inspect: [charlists: :as_lists])来配置iex(。

但是,您不需要重写测试。请记住,打印值的方式只是数据上的视图。它不会影响数据的存储方式。

您的示例断言失败,因为'stu'不等于'st',就像[115, 116, 117]不等于[115, 116]一样。

查看以下代码:

iex> [115, 116, 117] === 'stu'
true

左侧和右侧完全相等。单引号只允许人类更容易地输入数据。

在您的特定情况下,您可能需要查看MapSet,特别是如果您的ID列表是唯一的。然后,您可以避免在比较之前进行尴尬/脆弱的排序。使用MapSet,您可以比较两个集合的相等性。例如:

expected_ids = MapSet.new([115, 116, 117])
actual_ids = MapSet.new(some_function_output)
assert MapSet.equal?(actual_ids, expected_ids)

这可能有助于避免对骗子造成的错误进行乏味的追踪。在您的情况下,另一个选项可能是在映射期间将整数转换为字符串,例如Enum.map(list1, fn x -> to_string(x.id) end)

这在ExUnit中是不可配置的,它可以归结为调用Inspect.Algebra.to_doc/2Inspect.Opts硬编码为%Inspect.Opts{width: width}

在您自己的代码中,您可能总是在调用inspect/2时传递第二个参数,如

IO.inspect('ABC', charlists: :as_list)
#⇒ [65, 66, 67]

最新更新