Reputation: 768
I have yet another problem with testing in Elixir and Phoenix. I have a module which represents users which looks like so:
defmodule AppExample.Accounts.User do
use Ecto.Schema
import Ecto.Changeset
alias SecuritytrailsApi.Accounts.User
schema "users" do
field :email, :string
field :password, :string, virtual: true
field :password_hash, :string
field :last_login, :naive_datetime
timestamps()
end
...
def registration_changeset(%User{} = user, attrs \\ %{}) do
user
|> changeset(attrs) # validating and castnig email
|> validate_required([:password])
|> put_password_hash # creates password hash from password
|> set_default_date
end
defp set_default_date(chanegset) do
case changeset do
%Ecto.Changeset{valid?: true} ->
put_change(changeset, :last_login, Ecto.DateTime.utc)
_ -> changeset
end
end
end
And let's say I have an Accounts context which is responsible for creating new accounts. Like so:
defmodule AppExample.Accounts do
def create_user(attrs \\ %{}) do
%User{}
|> User.registration_changeset(attrs)
|> Repo.insert
end
end
So as you can ese, the field last_login
is inserted automatically using Ecto.DateTime.utc
to get the now() time. So, my questions are the following:
1) Is this the correct way of adding a default now()
value to a field in Ecto?
2) How can I write tests for this? I don't know how can I get the value of that particular field. Please check the example below for details.
defmodule AccountsTest do
@valid_attrs %{email: "[email protected]", password: "123123"}
test "create_user/1 creates a new users with last_login set to now" do
assert {:ok, %User{} = user} = Accounts.create_user(@valid_attrs)
assert user.email == "[email protected]"
assert user.last_login == ### ????? How can I get that NOW value here for the test
end
end
Upvotes: 1
Views: 1582
Reputation: 222138
1) Is this the correct way of adding a default now() value to a field in Ecto?
You can default this field to now()
in a migration instead of computing its value manually.
alter table(:users) do
modify :last_login, :string, default: fragment("now()")
end
2) How can I write tests for this?
You could assert that the value is in the last e.g. 15 seconds:
assert DateTime.diff(DateTime.utc_now, user.last_login, :second) <= 15
Upvotes: 6