testing - Elixir - 测试完整的脚本

标签 testing pattern-matching elixir phoenix-framework gen-server

我正在编写一个测试来检查一个函数(当新文件进入文件夹时由 GenServer 自动调用),该函数调用同一模块中的其他函数与管道以读取文件,处理其内容以插入它如果需要并返回一个列表(:errors 和 :ok 映射)。

结果看起来像:

[
          error: "Data not found",
          ok: %MyModule{
            field1: field1data,
            field2: field2data
          },
          ok: %MyModule{
            field1: field1data,
            field2: field2data
          },
          error: "Data not found"

代码:

  def processFile(file) do
    insertResultsMap =
      File.read!(file)
      |> getLines()
      |> extractMainData()
      |> Enum.map(fn(x) -> insertLines(x) end)
      |> Enum.group_by(fn x -> elem(x, 0) end)

    handleErrors(Map.get(insertResultsMap, :error))
    updateAnotherTableWithLines(Map.get(insertResultsMap, :ok))
  end

  defp getLines(docContent) do
    String.split(docContent, "\n")
  end

  defp extractMainData(docLines) do
    Enum.map(fn(x) -> String.split(x, ",") end)
  end

  defp insertLines([field1, field2, field3, field4]) do
    Attrs =  %{
      field1: String.trim(field1),
      field2: String.trim(field2),
      field3: String.trim(field3),
      field4: String.trim(field4)
    }

    mymodule.create_stuff(Attrs)
  end

  defp handleErrors(errors) do
    {:ok, file} = File.open(@errorsFile, [:append])
    saveErrors(file, errors)
    File.close(file)
  end

  defp saveErrors(_, []), do: :ok
  defp saveErrors(file, [{:error, changeset}|rest]) do
    changes = for {key, value} <- changeset.changes do
      "#{key} #{value}"
    end
    errors = for {key, {message, _}} <- changeset.errors do
      "#{key} #{message}"
    end

    errorData = "data: #{Enum.join(changes, ", ")} \nErrors: #{Enum.join(errors, ", ")}\n\n"

    IO.binwrite(file, errorData)
    saveErrors(file, rest)
  end

  defp updateAnotherTableWithLines(insertedLines) do
    Enum.map(insertedLines, fn {:ok, x} -> updateOtherTable(x) end)
  end

  defp updateOtherTable(dataForUpdate) do
    "CLOSE" -> otherModule.doStuff(dataForUpdate.field1, dataForUpdate.field2)
  end

我有几个问题,有些是非常基础的,因为我还在学习:

  • 你觉得这段代码怎么样?有什么建议吗? (考虑到我自愿混淆了名字)。
  • 如果我想测试这个,只测试 processFile 函数是否正确?或者我应该公开更多它们并单独测试它们吗?
  • 当我测试 processFile 函数时,我检查我是否收到了一个列表。有什么方法可以确保此列表只有我正在等待的元素,因此 error: "String"ok: %{}"?

最佳答案

What do you think of the code? Any advices? (take into account I voluntarily obfuscated names).

基于意见。

If I want to test this, is it the right way to test only processFile function?

是的。

Or should I make public more of them and test them individually?

不,这是一个实现细节,测试它是一种反模式。

When I test the processFile function, I check that I'm receiving a list. Any way to make sure this list has only elements I'm waiting for, thus error: "String" or ok: %{}"?

您收到一个关键字。要检查显式值,可以使用:

foo = processFile(file)
assert not is_nil(foo[:ok])

OTOH,我最好从那里返回一张 map 并对其进行模式匹配:

assert %{ok: _} = processFile(file)

要断言结果除了 :ok:error 之外没有任何内容,可以使用列表减法:

assert Enum.uniq(Keyword.keys(result)) -- [:ok, :error] == []

关于testing - Elixir - 测试完整的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53377630/

相关文章:

sql-server-2005 - 某处有 TSQLUnit 用户社区吗?

pattern-matching - Rakudo Perl 6 是否有类似 Scala 中的 case Class 的结构?

elixir - Ecto NoSQL 适配器的最低要求

elixir - 如何使用加载的关联序列化/反序列化 Ecto 模型?

linux - 如何根据给定模式在 linux 中从文件底部到顶部拆分文本文件

elixir - 在Phoenix的Elixir中设置暂存环境?

c# - 确定 Equals() 是否是重写?

testing - Laravel Artisan 错误 'LARAVEL_ENV' 未被识别为内部或外部命令

ruby-on-rails - 需要通过 Travis API 调用查看 repo 拉取请求的 Travis CI 测试统计信息

javascript - 使用 JavaScript 进行模式验证