You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:50:33