testing - 如何为 ExUnit 实现 "assert_difference"

标签 testing elixir ex-unit

我想测试一个函数如何改变数据库中的某些东西。我正在努力处理与以下 ActiveSupport::TestCase 测试用例等效的 ExUnit:

test "creates a database record" do
  post = Post.create title: "See the difference"
  assert_difference "Post.published.count" do
    post.publish!
  end
end

RSpec 版本更优雅,而且由于使用了 lambda,我认为它可以移植到 Elixir/ExUnit。

it "create a database record" do
  post = Post.create title: "See the difference"
  expect { post.publish! }.to change { Post.count }.by 1
end

有没有比这更优雅(阅读:功能性)的方法:

test "creates a database record", %{conn: conn} do
  records_before = count_records
  post(conn, "/articles")
  records_after  = count_records

  assert records_before == (records_after - 1)
end

defp count_records do
  MyApp.Repo.one((from a in MyApp.Article, select: count("*"))
end

最佳答案

您可以使用宏来获得类似于 Ruby 中的 TestUnit 和 RSpec 示例的东西:

defmacro assert_difference(expr, do: block) do
  quote do
    before = unquote(expr)
    unquote(block)
    after_ = unquote(expr)
    assert before != after_
  end
end

defmacro assert_difference(expr, [with: with], do: block) do
  quote do
    before = unquote(expr)
    unquote(block)
    after_ = unquote(expr)
    assert unquote(with).(before) == after_
  end
end

test "the truth" do
  {:ok, agent} = Agent.start_link(fn -> 0 end)

  assert_difference Agent.get(agent, &(&1)) do
    Agent.update(agent, &(&1 + 1))
  end

  {:ok, agent} = Agent.start_link(fn -> 0 end)

  assert_difference Agent.get(agent, &(&1)), with: &(&1 + 2) do
    Agent.update(agent, &(&1 + 2))
  end
end

但我不会使用它,除非它被大量使用,否则这只会让除了作者之外的每个人(可能)都更难理解代码。如果您确实使用它,您可能希望将它移动到不同的模块并将其导入到您的测试模块中。

关于testing - 如何为 ExUnit 实现 "assert_difference",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39744696/

相关文章:

angular - 尝试从 Angular 应用程序中的服务模拟后端结果的 Karma 测试错误

elixir - 检查 Elixir 的保护条款中的列表列表

elixir - 如何测试 Elixir GenStage Consumer?

angular - 如何使用 Protractor 捕获 <mat-error> 错误消息文本内容

ruby-on-rails-3 - rails 通过 :id or :name 路由可选参数类型

Elixir - 将字符串转换为不同的类型

elixir - __struct__/1 未定义,无法扩展 struct Gazette.User

elixir - 如何在运行 ExUnit 测试时仍将日志打印到控制台?

testing - jMeter 没有收到一些 cookie