From 7a5a742a5a49bdd052129a714f14e0b5f227b885 Mon Sep 17 00:00:00 2001 From: Kayla Firestack Date: Sat, 12 Oct 2024 15:57:49 -0400 Subject: [PATCH] refactor:test(ex): use `DataCase.setup_sandbox` acording to `phx.new` template feat:test(ex/test): add database `setup_sandbox` function to `DataCase` This allows other test cases to configure the database via a shared function --- test/support/conn_case.ex | 16 +++++++--------- test/support/data_case.ex | 27 ++++++++++++++------------- test/test_helper.exs | 2 ++ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index b67c90d7c..24ed4fc1f 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -8,9 +8,11 @@ defmodule SkateWeb.ConnCase do to build common data structures and query the data layer. Finally, if the test case interacts with the database, - it cannot be async. For this reason, every test runs - inside a transaction which is reset at the beginning - of the test unless the test case is marked as async. + we enable the SQL sandbox, so changes done to the database + are reverted at the end of every test. If you are using + PostgreSQL, you can even run database tests asynchronously + by setting `use SkateWeb.ConnCase, async: true`, although + this option is not recommended for other databases. """ use ExUnit.CaseTemplate @@ -32,15 +34,11 @@ defmodule SkateWeb.ConnCase do end setup tags do - alias Ecto.Adapters.SQL.Sandbox - :ok = Sandbox.checkout(Skate.Repo) + Skate.DataCase.setup_sandbox(tags) + username = "test_user" email = "test_user@test.com" - unless tags[:async] do - Sandbox.mode(Skate.Repo, {:shared, self()}) - end - user = User.upsert(username, email) resource = %{id: user.id} diff --git a/test/support/data_case.ex b/test/support/data_case.ex index c7b86c4db..053c35f28 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -7,9 +7,11 @@ defmodule Skate.DataCase do your tests. Finally, if the test case interacts with the database, - it cannot be async. For this reason, every test runs - inside a transaction which is reset at the beginning - of the test unless the test case is marked as async. + we enable the SQL sandbox, so changes done to the database + are reverted at the end of every test. If you are using + PostgreSQL, you can even run database tests asynchronously + by setting `use Skate.DataCase, async: true`, although + this option is not recommended for other databases. """ use ExUnit.CaseTemplate @@ -26,19 +28,18 @@ defmodule Skate.DataCase do end setup tags do - :ok = Ecto.Adapters.SQL.Sandbox.checkout(Skate.Repo) - - unless tags[:async] do - Ecto.Adapters.SQL.Sandbox.mode(Skate.Repo, {:shared, self()}) - end - - on_exit(fn -> - Ecto.Adapters.SQL.Sandbox.checkin(Skate.Repo) - end) - + Skate.DataCase.setup_sandbox(tags) :ok end + @doc """ + Sets up the sandbox based on the test tags. + """ + def setup_sandbox(tags) do + pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Skate.Repo, shared: not tags[:async]) + on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end) + end + @doc """ A helper that transform changeset errors to a map of messages. diff --git a/test/test_helper.exs b/test/test_helper.exs index 8eeaaf6ef..56cb0a320 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -11,6 +11,8 @@ ExUnit.start( ] ) +Ecto.Adapters.SQL.Sandbox.mode(Skate.Repo, :manual) + Mox.defmock(Skate.OpenRouteServiceAPI.MockClient, for: Skate.OpenRouteServiceAPI.Client) Application.put_env(:skate, Skate.OpenRouteServiceAPI,