【问题标题】:How can I do string interpolation inside a doctest in Elixir?如何在 Elixir 的 doctest 中进行字符串插值?
【发布时间】:2018-01-12 12:18:32
【问题描述】:

我一直在 Elixir 中尝试 doctests,它一直运行良好,直到我尝试进行字符串插值。

代码如下:

  @doc"""
  Decodes the user resource from the sub claim in the received token for authentication.

  ## Examples

      iex> attrs = %{email: "test@example.com", password: "password", password_confirmation: "password"}
      iex> {:ok, user} = Accounts.create_user(attrs)
      iex> resource_from_claims(%{"sub" => "User:#{user.id}"})
      {:ok, %User{}}

  """
  def resource_from_claims(%{"sub" => "User:" <> id}) do
    resource = Accounts.get_user(id)
    case resource do
      nil -> {:error, :no_result}
      _ -> {:ok, resource}
    end
  end

运行mix test时出现此错误:

变量“user”不存在,正在扩展为“user()”,请使用括号消除歧义或更改变量名

我可以确认user 变量确实存在并且几乎可以在其他所有内容上工作,除非我尝试将它放在字符串插值中。

还有其他方法可以在 doctests 中进行字符串插值吗?

编辑:看起来我收到了这个错误,因为@doc 中的字符串插值部分实际上是在 doctest 范围之外运行,而是作为模块本身的一部分运行.我将看看是否有另一种方法可以在 doctest 的上下文中进行字符串插值。

【问题讨论】:

    标签: testing elixir


    【解决方案1】:

    发布编辑后(见上文),我发现解决方案是用~S 调用@doc 字符串:

      @doc ~S"""
      Decodes the user resource from the sub claim in the received token for authentication.
    
      ## Examples
    
          iex> attrs = %{email: "test@example.com", password: "password", password_confirmation: "password"}
          iex> {:ok, user} = Accounts.create_user(attrs)
          iex> resource_from_claims(%{"sub" => "User:#{user.id}"})
          {:ok, %User{}}
    
      """
    

    这样,模块将忽略@doc 块内写入的任何字符串插值,这将允许 doctest 执行字符串插值。

    参考:https://github.com/elixir-lang/elixir/issues/2512

    【讨论】:

    • 这与 doctest 本身无关~S sigil 与 ~s 不同,它自己阻止插值。
    • @mudasobwa 怎么样?如果没有~S,doctest 会失败,因为模块已经进行了插值,这会导致编译错误。我认为~s 不会解决我的问题,因为我需要 doctest 来进行插值。
    • 我的意思是,您需要防止插入整个评论字符串。不管是注释字符串,还是代码库中某处的纯字符串,都没有关系。 ~S unlike ~sunlike 普通 """,阻止了这种插值。就是这样。
    猜你喜欢
    • 1970-01-01
    • 2021-09-28
    相关资源
    最近更新 更多