Search code examples
testingelixirphoenix-frameworkecto

Phoenix Framework: What's the correct way to seed database for testing?


I am building my first Phoenix app and am trying to write a test that will verify that the user retrieved from a JWT in a connection's Authentication header is the correct user, is authenticated, etc.

What is the correct way to seed the database with a single record for this test?

Should it be done:

  • globally, using the test/test_helper.exs file, by requiring priv/repo/seeds.exs and executing manual Ecto operations

OR

  • per test (in which case I am not certain how best to proceed)

Finally, what is the correct way to clean out the test database after successfully running my tests, so I can avoid trying to create the same record every time I run a test?


Solution

  • Usually the best way is to keep your tests separated from each other and init everything per test. Tests are run inside Ecto transactions so everything is rolled back at the end and there is no junk left. This also allows running tests in parallel. But it means the user has to be inserted at the beginning of every test manually. If you have more tests that depend on the user and current session you can extract this common code to a tag.

    Usually data about logged in user is kept in conn.assigns. Lets pretend that it is under key :user.

    Inside your App.ConnCase setup function add something like this:

    setup %{conn: conn} = config do
      my_user_email = config[:logged_as]
      cond do
        my_user_email ->
          {:ok, user} = Repo.insert(...)
          conn_with_user = assign(conn, :user, user)
          {:ok, conn: conn_with_user, user: user}
      end
    

    and now in your tests you can match on both conn and new account:

    @logged_as "[email protected]"
    test "JWT works correctly", %{conn: conn, user: user} do
      # user is now in the db
      # you don't have to retrieve it, because it is passed with test setup
      # you can start testing JWT 
    end
    

    This method is described in Programming Phoenix. I really recommend that book!