tar*_*gaf 5 elixir ecto phoenix-framework
我正在尝试测试数据库中的唯一性,但遇到了一些麻烦。我运行了此迁移:
def change do
create table(:signups) do
add :name, :string
add :email, :string
timestamps()
end
create unique_index(:signups, [:email])
end
Run Code Online (Sandbox Code Playgroud)
在我的模型中有这个changeset def:
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name, :email])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> update_change(:email, &String.downcase/1)
|> unique_constraint(:email)
end
Run Code Online (Sandbox Code Playgroud)
而失败的测试是:
test "duplicate email changeset is invalid" do
%Signup{}
|> Signup.changeset(@valid_attrs)
|> Repo.insert!
user2 = %Signup{}
|> Signup.changeset(@valid_attrs)
assert {:error, _changeset} = Repo.insert(user2)
end
Run Code Online (Sandbox Code Playgroud)
第二个插入似乎通过了,尽管它没有通过。返回的确切错误是:
1) test duplicate email changeset is invalid (EventSignup.SignupTest)
test/models/signup_test.exs:24
match (=) failed
code: {:error, _changeset} = Repo.insert(user2)
rhs: {:ok,
%EventSignup.Signup{__meta__: #Ecto.Schema.Metadata<:loaded, "signups">,
email: "some@content.com", id: 41,
inserted_at: #Ecto.DateTime<2016-09-11 19:35:40>,
name: "some content",
updated_at: #Ecto.DateTime<2016-09-11 19:35:40>}}
stacktrace:
test/models/signup_test.exs:31: (test)
Run Code Online (Sandbox Code Playgroud)
有人看到我在这里想念的吗?如果我通过iex手动插入两个相同的记录,则第二次插入将失败,但在测试过程中会通过。
小智 5
我认为您的迁移和模型是正确的。但是当您应该执行以下操作时,似乎在断言宏上使用=:
test "duplicate email changeset is invalid" do
%Signup{}
|> Signup.changeset(@valid_attrs)
|> Repo.insert!
user2 = %Signup{}
|> Signup.changeset(@valid_attrs)
{:error, changeset} = Repo.insert(user2)
refute changeset.valid?
end
Run Code Online (Sandbox Code Playgroud)
这是我的测试工作。
test "only one setting per company" do
first_setting = insert(:setting)
second_setting = params_for(:setting, %{company_id: first_setting.company.id})
changeset = Setting.changeset(%Setting{}, second_setting)
{:error, changeset} = Repo.insert changeset
assert changeset.errors == [company_id: {"has already been taken", []}]
refute changeset.valid?
end
Run Code Online (Sandbox Code Playgroud)
insert是来自ex-machina的帮助方法,该方法创建有效的模型,并且params返回具有相同company_id的有效映射以强制发生错误。
在测试环境中运行iexMIX_ENV=test iex -S mix并尝试插入两条具有相同值的记录。如果它允许您这样做,则意味着您的测试数据库缺少 unique_index。重要的!请记住之后清理您的测试数据库。
或者:
跳过上面的描述并运行MIX_ENV=test mix ecto.reset然后再次运行测试。如果他们通过了您的测试数据库则缺少 unique_index。