我目前正在测试使用create_zone函数的控制器,该函数依赖于检索用户以将所述用户与区域相关联的函数,然后创建仅作为两个条目的关联表的参与者条目。
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
我如何仅仅为了测试目的而模拟或创建它?
答案 0 :(得分:1)
不要嘲笑它,用ex_machina创建它:https://github.com/thoughtbot/ex_machina
在Elixir中不鼓励嘲弄:http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/(你现在真的不需要阅读它,但是如果你想要模拟一些外部资源,请阅读它。)
答案 1 :(得分:1)
您可以编写一个使用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章。