joshua.aug

joshua.aug

How to rollback db changes between tests

I have multiple tests in one file. I want to create users at the beginning of each test and roll back those db changes at the end of each test.
At the top of my file I have this:

  use Teiserver.DataCase, async: true

which references this module

defmodule Teiserver.DataCase do


  use ExUnit.CaseTemplate

  using do
    quote do
      alias Teiserver.Repo

      import Ecto
      import Ecto.Changeset
      import Ecto.Query
      import Teiserver.DataCase
    end
  end

  @doc """
  Sets up the sandbox based on the test tags.
  """
  def setup_sandbox(tags) do
    pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Teiserver.Repo, shared: not tags[:async])
    on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
  end

  setup tags do
    setup_sandbox(tags)
    :ok
  end

  @doc """
  A helper that transforms changeset errors into a map of messages.

      assert {:error, changeset} = Accounts.create_user(%{password: "short"})
      assert "password is too short" in errors_on(changeset).password
      assert %{password: ["password is too short"]} = errors_on(changeset)

  """
  def errors_on(changeset) do
    Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
      Regex.replace(~r"%{(\w+)}", message, fn _, key ->
        opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
      end)
    end)
  end
end

However it seems like my changes are persisted between tests.

Also test_helper.exs has this

ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(Teiserver.Repo, :manual)

alias Teiserver.Repo
alias Central.Helpers.GeneralTestLib

:ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo, sandbox: false)

if not GeneralTestLib.seeded?() do
  GeneralTestLib.seed()
  Teiserver.TeiserverTestLib.seed()
end

Ecto.Adapters.SQL.Sandbox.checkin(Repo)

How do I make it so any db changes are rolled back after each test?

You can see the video in this link where I run the same test multiple times and it will just randomly fail eventually.

First Post!

dimitarvp

dimitarvp

What’s wrong with using setup? It gets invoked before each test. And whatever you create in your each test should be automatically rolled back by Ecto at the end of each test. Have you tried?

As an experiment to maybe increase understanding, try putting that file in your project (f.ex. directly inside test/):

defmodule Stuff.AndStuffTest do
  setup do
    IO.puts("before each test")
    %{stuff: :you_need}
  end

  test "one thing", context do
    IO.inspect(context)
  end

  test "another thing", context do
    IO.inspect(context)
  end
end

…and run mix test test/stuff_and_stuff_test.exs, and see what output you are getting.

Last Post!

arcyfelix

arcyfelix

Have you tried on_exit/2?

Edit. I see you did that in your macro.

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40165 209
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement