Phoenix Elixir:模拟内部函数
问题描述:
我目前正在测试控制器,该控制器使用函数create_zone,该函数依赖于检索用户将所述用户关联到区域的功能,然后创建只是两者的关联表的参与者条目条目。Phoenix Elixir:模拟内部函数
def create_zone(attrs \\ %{}, user_id) do
user = Accounts.get_user!(user_id)
with{:ok, %Zone{} = zone} <- %Zone{}
|> Zone.changeset(attrs,user)
|> Repo.insert()
do
create_participant(zone,user)
end
end
我想用ExUnit测试它,但问题是测试框架试图搜索数据库中不存在的记录。
** (Ecto.NoResultsError) expected at least one result but got none in query:
from u in Module.Accounts.User,
where: u.id == ^1
我该如何模拟或创建它仅用于测试目的?
答
不要嘲笑它,与ex_machina创建:https://github.com/thoughtbot/ex_machina
嘲讽不鼓励在药剂:http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/(你并不真的需要现在读它,但如果你想嘲笑一些外部资源, 阅读)。
答
您可以编写一个使用Ecto插入数据库的简单工厂模块。测试将被包装在数据库事务中,并由于Ecto.Sandbox而自动回滚。
defmodule Factory do
def create(User) do
%User{
name: "A. User",
email: "user_#{:rand.uniform(10000)}@mail.com"
}
end
def create(Zone) do
%Zone{
# ... random/default zone attributes here...
}
end
def create(schema, attrs) do
schema
|> create()
|> struct(attributes)
end
def insert(schema, attrs \\ []) do
Repo.insert!(create(schema, attrs))
end
end
测试中的自定义属性
然后合并与出厂默认设置,包括协会。
test "A test" do
user = Factory.insert(User, name: "User A")
zone = Zones.create_zone(user.id)
assert zone
end
有关更详细的解释,请参阅what's new in ecto 2.1的第7章。
+1
谢谢。我结束了使用ex_machina,它基本上是一样的,但是在一个更易于使用的界面中。 – user2070502
用它来嘲笑它吗? https://github.com/eproxus/meck不适合你?该功能是公开的,所以它应该工作。 – Dogbert