elixir - Elixir:将混合项目配置为始终将字符列表打印为列表?
问题描述
在测试我的 Phoenix 应用程序时,我经常遇到需要比较预期记录 ID 列表和实际记录 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/charstrings。我编写了 Ruby 风格的 Elixir,而且我几乎从不使用 charlists,对我来说,它们主要是一个可以解决的问题。
感谢这个答案,我知道有一种方法可以将 IEx 配置为始终将整数列表打印为列表。有没有办法在 Mix 中这样做,或者在 Elixir 本身中全局这样做,所以mix test
会采用这种行为吗?
解决方案
charlists 的“人性化”可能是 Elixir 中最令人困惑的问题之一。正如@Aleksei指出的那样,这是不可配置的ExUnit
(尽管您可以通过iex
添加文件来配置)。IEx.configure(inspect: [charlists: :as_lists])
.iex.exs
但是,您不需要重写测试。请记住,打印值的方式只是数据的视图。它不影响数据的存储方式。
您的示例断言失败,因为'stu'
is not equal to 'st'
just as [115, 116, 117]
is not equal to [115, 116]
。
看下面的代码:
iex> [115, 116, 117] === 'stu'
true
左侧和右侧是 100% 完全等效的。单引号仅允许人们更轻松地输入数据。
在您的特定情况下,您可能需要查看MapSet
,特别是如果您的 ID 列表是唯一的。然后,您可以避免在比较之前进行尴尬/脆弱的排序。使用MapSet
,您可以只比较两组是否相等。例如:
expected_ids = MapSet.new([115, 116, 117])
actual_ids = MapSet.new(some_function_output)
assert MapSet.equal?(actual_ids, expected_ids)
这可能有助于避免冗长的跟踪由 charlists 引起的错误。在您的情况下,另一种选择可能是在映射期间将整数转换为字符串,例如Enum.map(list1, fn x -> to_string(x.id) end)
推荐阅读
- assembly - 使用easy68K添加一系列整数的子程序
- android - 找不到资源样式/LaunchTheme
- c# - 在 Visual Studio 2017 中更改 MVC 文件夹结构
- python - stripe:如何将条带模型对象转换为 JSON 以获得完整的分层数据?
- python-3.x - 带有签名的芹菜和弦KeyError
- html - 具有只读输入我无法复制值
- asp.net - WebApi 返回序列化的 HttpResponseMessage 而不是 text/html
- python-3.x - 在python的'for'循环中计算NaN
- wordpress - WooCommerce - 不要授权或捕获新订单
- c# - 如何使用多线程或 c# 中的任何其他机制在 Windows 服务中同时处理多个请求?