如何为 ExUnit 实现 "assert_difference"
How to implement an "assert_difference" for ExUnit
我想测试函数如何更改数据库中的内容。我正在努力处理与以下 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
您可以使用宏来获得接近 TestUnit 的东西和来自 Ruby 的 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
但我不会使用它,除非它被大量使用 很多 否则这只会让除了作者之外的每个人(可能)都更难理解代码。如果你确实使用它,你可能想将它移动到不同的模块并将其导入你的测试模块。
我想测试函数如何更改数据库中的内容。我正在努力处理与以下 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
您可以使用宏来获得接近 TestUnit 的东西和来自 Ruby 的 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
但我不会使用它,除非它被大量使用 很多 否则这只会让除了作者之外的每个人(可能)都更难理解代码。如果你确实使用它,你可能想将它移动到不同的模块并将其导入你的测试模块。