user2070502
user2070502

Reputation: 683

Phoenix Elixir: mock internal functions

I'm currently testing controller that uses the function create_zone that depends on a function that retrieves a user to associates said user to a zone and then creates a participant entry that is only an association table of both entries.

  def create_zone(attrs \\ %{}, user_id) do
    user = Accounts.get_user!(user_id)

    with{:ok, %Zone{} = zone} <- %Zone{}
    |> Zone.changeset(attrs,user)
    |> Repo.insert()
    do
    create_participant(zone,user)
   end
  end

And I would like to test it using ExUnit but the problem is that the testing framework tries to search a non existent record in the database.

** (Ecto.NoResultsError) expected at least one result but got none in query:
   from u in Module.Accounts.User,
   where: u.id == ^1

How could I mock or create it just for testing purposes?

Upvotes: 1

Views: 965

Answers (2)

Mike Buhot
Mike Buhot

Reputation: 4885

You can write a simple factory module that uses Ecto to insert into the database. The test will be wrapped in a database transaction and rolled back automatically thanks to the Ecto.Sandbox.

defmodule Factory do
  def create(User) do
    %User{
      name: "A. User",
      email: "user_#{:rand.uniform(10000)}@mail.com"
    }
  end

  def create(Zone) do
    %Zone{
       # ... random / default zone attributes here...
    }
  end

  def create(schema, attrs) do
    schema
    |> create()
    |> struct(attributes)
  end

  def insert(schema, attrs \\ []) do
    Repo.insert!(create(schema, attrs))
  end
end

Then in your test custom attributes are merged with the factory defaults, including associations.

test "A test" do
  user = Factory.insert(User, name: "User A")
  zone = Zones.create_zone(user.id)
  assert zone
end

See chapter 7 of what's new in ecto 2.1 for a more detailed explanation.

Upvotes: 1

denis.peplin
denis.peplin

Reputation: 9841

Don't mock it, create it with ex_machina: https://github.com/thoughtbot/ex_machina

Mocking is discouraged in Elixir: http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/ (you don't really need to read it now, but in case you are want to mock some external resource, read it).

Upvotes: 1

Related Questions