首页 > 解决方案 > 在 Phoenix 中测试返回 nil 的虚拟场

问题描述

我有一个基本user模式,其中包含password_digest要保存在数据库password中的用户将输入、散列、保存为密码摘要的虚拟字段。

问题是在测试时,我在比较的一侧将密码设置为 nil,而在另一侧我将密码设置为非 nil。我不确定测试虚拟字段时的最佳做法是什么。

错误信息:

...
Assertion with == failed
 code:  assert Accounts.get_user!(user.id()) == user
 left:  ... username: "some username", password: nil}
 right: ... username: "some username", password: "some password"}

  schema "users" do
    field :email, :string
    field :password_digest, :string
    field :username, :string

    timestamps()

    field :password, :string, virtual: true
  end

以下是相关代码:

def changeset(user, attrs) do
    user
    |> cast(attrs, [:username, :email, :password])
    |> hash_password
    |> validate_required([:username, :email, :password, :password_digest])
  end

  defp hash_password(changeset) do
    if password = get_change(changeset, :password) do
      changeset
      |> put_change(:password_digest, hashpwsalt(password))
    else
      changeset
    end
  end

在测试中,我有这些:

@valid_attrs %{email: "some email", password: "some password", username: "some username"}


def user_fixture(attrs \\ %{}) do
  {:ok, user} =
    attrs
    |> Enum.into(@valid_attrs)
    |> Accounts.create_user()

  user
end

...

test "get_user!/1 returns the user with given id" do
  user = user_fixture()
  assert Accounts.get_user!(user.id) == user
end

顺便说一句,get_user 直接来自生成器:def get_user!(id), do: Repo.get!(User, id)

测试虚拟场的正确方法是什么?

标签: testingphoenix-framework

解决方案


这是预期的行为,因为Accounts.get_user!(user.id)不会填充虚拟属性。它仅在变更集上更改,您没有进行任何更改。

在这种情况下,我认为与您相关的是测试是否password_digest已设置。


推荐阅读