返回结构时编写doctest

时间:2018-08-17 10:28:36

标签: elixir ex-unit

一个类似问题的答案为this question

  

要使用doctests测试功能,您必须能够预测功能的输出。

问题

正如标题中所述,我想坚持使用doctests,但这似乎行不通,而且我不认为没有办法。

代码

  @doc """
  Update a field(s) in a setting record

  ## Examples

      iex> example = Setting.get(id: 4)
      iex> Setting.update(example, %{keyname: "an_example"})
      {:ok, %Elements.Setting{_}}


  """
  @spec update(struct :: Elements.Setting, changes :: map()) :: {:ok, Ecto.Schema} | {:error, Ecto.Changeset.t()}
  def update(struct, changes) do
    ...
  end

上面是我一直在尝试的代码及其变体。例如,使用_时数据将是意外的。只是那些不会改变的位。

例如,理想情况下,我希望返回值看起来像{:ok, %Elements.Setting{keyname: "an_example", _}。因此,文档通过了,但用户阅读的内容也很清楚,并且可以看到之前的代码的效果。

iex

iex(6)> Setting.update(example, %{keyname: "an_example"})
{:ok,
 %Elements.Setting{
   __meta__: #Ecto.Schema.Metadata<:loaded, "settings">,
   children: #Ecto.Association.NotLoaded<association :children is not loaded>,
   id: 4,
   inserted_at: ~N[2018-08-17 07:53:23.000000],
   keyname: "an_example",
   name: "Display Breadcrumb",
   parent: #Ecto.Association.NotLoaded<association :parent is not loaded>,
   parent_id: 2,
   updated_at: ~N[2018-08-17 10:29:46.707878]
 }}

根据一开始引用的答案,您可能会注意到,至少inserted_at: ...updated_at: ...将会有所不同,这意味着测试将始终失败。

有什么可以做的,甚至可以解决的方法吗?

1 个答案:

答案 0 :(得分:0)

您应该将文档放在%Elements.Setting{}所属的位置(定义此结构的模块)上,并坚持匹配您刚刚明确设置的内容:

iex> example = Setting.get(id: 4)
iex> with {:ok, %Setting{} = result} <- Setting.update(example, %{keyname: "an_example"}),
...>   do: result.keyname == "an_example"
true

您想要显示的值是特定于测试的,并且对于应该阅读文档的任何人都是非常误导的。