Elixir doctest未捕获带强制键结构体的错误问题
Elixir 结构体强制键的 DocTest 失败问题解决办法
为啥测试会失败
你的 DocTest 跑不通,核心原因是 Elixir 的 DocTest 对异常输出的匹配要求完全丝毫不差——包括空格、键的顺序甚至符号格式,哪怕差一个空格都会匹配失败。另外如果你的缩进格式不符合 DocTest 的解析规则,也会导致识别不到异常。
解决办法
办法1:确保异常消息完全一致
先核对实际抛出的错误消息和你写的是否完全一样。比如@enforce_keys里的键顺序是[:name, :type, :health, :attack, :speed],缺失的键会按照这个顺序列出来,如果你写的错误消息里键的顺序不对(比如写成[:attack, :health]),就会匹配失败。
修正后的代码示例:
@moduledoc """ Pokemon ## Examples iex> %Pokemon{name: "Charmander", type: :fire, speed: 20} ** (ArgumentError) the following keys must also be given when building struct Pokemon: [:health, :attack] """ @enforce_keys [:name, :type, :health, :attack, :speed] defstruct [:name, :type, :health, :attack, :speed]
办法2:用正则表达式模糊匹配
不想纠结严格的字符串匹配?可以用正则表达式来匹配错误消息,这样能容忍键顺序变化这类小差异:
@moduledoc """ Pokemon ## Examples iex> %Pokemon{name: "Charmander", type: :fire, speed: 20} ** (ArgumentError) ~r/the following keys must also be given when building struct Pokemon: \[:(health|attack), :(attack|health)\]/ """ @enforce_keys [:name, :type, :health, :attack, :speed] defstruct [:name, :type, :health, :attack, :speed]
办法3:显式捕获异常(备选方案)
也可以在 DocTest 里用rescue显式捕获异常,直接验证错误消息:
@moduledoc """ Pokemon ## Examples iex> try do ...> %Pokemon{name: "Charmander", type: :fire, speed: 20} ...> rescue ...> e in ArgumentError -> e.message ...> end "the following keys must also be given when building struct Pokemon: [:health, :attack]" """ @enforce_keys [:name, :type, :health, :attack, :speed] defstruct [:name, :type, :health, :attack, :speed]
排查技巧
跑测试的时候加--trace参数,能看到 DocTest 实际输出和你预期的差异,快速定位哪里不匹配:
mix test --trace
内容的提问来源于stack exchange,提问作者user15254140
相关产品推荐
相关产品推荐

