create user with fixture and use id in @valid_attrs in phoenix controller test

Viewed 339

I'm very new to phoenix and elixir so thank you for your help and corrections!

I'm trying to use a fixture to create a user and user their id for the @valid_attrs and @update_attrs. However I'm not sure how to get access to the user created by the fixture in the describe block.

  describe "my test" do
    alias MyApp.Context.Module
    user = user_fixture()
    @valid_attrs %{name: "some name", user_id: user.id}
    @update_attrs %{name: "some updated name", user_id: user.id}
    @invalid_attrs %{name: nil, user_id: nil}
    ...
  end

However when I run mix test for the above I get

== Compilation error in file test/little_things/character_test.exs ==
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.410.0>.

My other tests successfully use the user_fixture in the setup method

   describe "another example test" do
    setup do
     %{user: user_fixture()}
    end
    test "example test using setup", %{user: user} do
      IO.puts(user.id) # This will print the user id
    end
  end

However I find it overly verbose to write, and would like to pre-define valid_attrs that I can use throughout my tests without having to pass the value in using the second param in test/2

How can I use the user variable in @valid_attrs and @updated_attrs? or is there another more DRY approach I can take?

2 Answers

ExUnit.Case.describe/2 might have its own setup/1 callback, so the below should work.

describe "my test" do
  setup do
    user = user_fixture()
    [
      user: user,
      valid_attrs: %{name: "some name", user_id: user.id},
      update_attrs: %{name: "some updated name", user_id: user.id},
      invalid_attrs: %{name: nil, user_id: nil}
    ]
  end

  test "foo", %{user: user, valid_attrs: valid_attrs, ...} do
    ...

To DRY, one might put the initialization into a separate private function (defp fixt_user, do: ...) and pass it to setup/1 as

  setup [:fixt_user]

I still haven't found a solution to the original question, but I have found a workaround using setup.

If anyone knows how to answer the original question I would really appreciate it! Though this works for now I think the syntax is still overly verbose

setup do
  user = user_fixture()
  %{
    valid_attrs: %{name: "some name", user_id: user.id}
  }
end

test "my test", %{valid_attrs: valid_attrs} do
   assert {:ok, %Pet{} = pet} = Character.create_pet(valid_attrs)
   assert pet.name == "some name"
end

I've edited the example to make it more clear why I want the user_id as a key in valid_attrs

Related