【问题标题】:Testing HashSets in doctest在 doctest 中测试 HashSet
【发布时间】:2015-06-26 20:43:01
【问题描述】:

我正在尝试通过 iex 使用 doctest 测试 HashSet。如果我运行下面的行,它会给出相同的结果,但 #HashSet<["rockerboo"]>} 不能在语法中表示。我想不出一种正确表示它的方法,也找不到任何例子。谢谢!

  @doc """
  Adds user to HashSet in state

  ## Examples
      iex> Elirc.Channel.add_user_to_state("rockerboo", %{users: HashSet.new})
      %{users: #HashSet<["rockerboo"]>}
  """
  def add_user_to_state(user, state) do
    %{state | users: HashSet.put(state.users, user) }
  end

运行mix test时,出现以下错误。

 Doctest did not compile, got: (TokenMissingError) lib/elirc/channel.ex:99: missing terminator: } (for "{" starting at line 99)
 code: %{users: #HashSet<["rockerboo"]>}

第 99 行是%{state...

【问题讨论】:

    标签: testing hashset elixir doctest


    【解决方案1】:

    你可以用不同的方式构造你的HashSet,使它成为一个有效的 Elixir 表达式。例如,这对我有用:

    ## Examples
      iex> Elirc.Channel.add_user_to_state("rockerboo", %{users: HashSet.new})
      %{users: ["rockerboo"] |> Enum.into(HashSet.new)}
    

    这也是ExUnit.DocTest documentation在“不透明类型”下推荐的方法

    【讨论】:

      【解决方案2】:

      Paweł 的回答是正确的。另一种选择是“按摩” doctest 中的数据。例如,这会起作用:

        iex> state = Elirc.Channel.add_user_to_state("rockerboo", %{users: HashSet.new})
        iex> state.users
        #HashSet<["rockerboo"]>
      

      或者:

        iex> state = Elirc.Channel.add_user_to_state("rockerboo", %{users: HashSet.new})
        iex> Enum.to_list(state.users)
        ["rockerboo"]
      

      我扩展了 Paweł 链接的 doctest 部分,以包括他和我的示例:https://github.com/elixir-lang/elixir/blob/64e5f4876007d840edee3040c43e8f98095b8e3d/lib/ex_unit/lib/ex_unit/doc_test.ex#L77

      【讨论】:

        【解决方案3】:

        你的问题是你试图表示一些不可能的东西,一个没有键或没有值的 HashDict 条目。 HashDict.put(state.users, "rockerboo") 会失败,因为 put 需要 3 个参数、一个 HashDict、一个键和一个值。假设你有类似name: "rockerboo" 的东西:

        iex> %{users: Enum.into([name: "rockerboo"], HashDict.new)} %{users: #HashDict<[name: "rockerboo"]>}

        上述工作按预期工作。

        【讨论】:

        • 嗯,这就是我没有正确阅读的结果,您使用的是 HashSet 而不是 HashDict :/。好吧,我还是把它留在这里,因为它可能对处于类似情况的其他人有所帮助。
        • 这个答案实际上是错误的,因为问题在于 HashDict 是一个不透明的数据结构,#HashDict 将始终被解析为注释。
        • @JoséValim 好吧,我基本上从文档中逐字提取了这个答案:iex&gt; Enum.into([a: 10, b: 20], HashDict.new) #HashDict&lt;[b: 20, a: 10]&gt;
        • 在文档中它工作正常,因为 doctest 断言以 #HashDict&lt; 开头。如果你把它放在地图中,那么所有的赌注都会被取消,因为它被视为评论。我已经改进了 doctest 文档以使这一切更加清晰。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多