Help me debug database access testing code

I want to build a genserver which takes data from my database. It should give me a list of all the data which is inside my database. After doing some work I’m stuck

defmodule Gorm.Test do
  use GenServer
  alias Gorm.Accounts

  def start_link(args) do
    GenServer.start_link(__MODULE__, args, name: __MODULE__)
  end

  def init(_args) do
    {:ok, []}
  end

  def list() do
    GenServer.call(__MODULE__, :list)
  end

  def handle_call(:list, _from, state) do
    my_models = Accounts.Repo.all(User)

    {:reply, my_models, state}
  end
end

How do I test this?

Let us know what you have tried and where you have looked for information. I googled “test genserver elixir” and got some answers. For example, the documentation: https://elixir-lang.org/getting-started/mix-otp/genserver.html#testing-a-genserver. Did you try this, what happened?

There are some very knowledgable and helpful people on the forums, but I think you are more likely to get help if you show that you have made some effort to help yourself and your questions are more specific.

1 Like

This is what I was trying

defmodule Gorm.DatabaseTest do
  use ExUnit.Case
  alias Gorm.Accounts
  alias Gorm.Accounts.User
  alias Gorm.Repo
  alias Gorm.Database

  test "test" do
    assert [] = Database.handle_call(:list, make_ref(), %{})

    Accounts.Repo.insert!(%User{name: "good", email: "ssiddhant@gmail.com"})

    assert {:reply, [my_model], %{}} = MyGenServer.handle_call(:list, make_ref(), %{})
  end
end

… and the problem was…

This is the error I’m getting

test test (Gorm.DatabaseTest)
     test/gorm/database_test.ex:8
     ** (UndefinedFunctionError) function Gorm.Accounts.Repo.all/1 is undefined (module Gorm.Accounts.Repo is not available)
     code: assert [] = Database.handle_call(:list, make_ref(), %{})
     stacktrace:
       Gorm.Accounts.Repo.all(User)
       (gorm) lib/gorm/database.ex:18: Gorm.Database.handle_call/3
       test/gorm/database_test.ex:9: (test)



Finished in 0.06 seconds
1 test, 1 failure

Even though I have added the Repo module

You are accessing the Repo correctly in your test, but incorrectly in your Genserver

1 Like

Now I’m getting this error

  1) test test (Gorm.DatabaseTest)
     test/gorm/database_test.ex:8
     ** (Protocol.UndefinedError) protocol Ecto.Queryable not implemented for User of type Atom, the given module does not exist. This protocol is implemented for the following type(s): BitString, Tuple, Ecto.Query, Atom, Ecto.SubQuery
     code: assert [] = Database.handle_call(:list, make_ref(), %{})
     stacktrace:
       (ecto) lib/ecto/queryable.ex:40: Ecto.Queryable.Atom.to_query/1
       (ecto) lib/ecto/repo/queryable.ex:14: Ecto.Repo.Queryable.all/3
       (gorm) lib/gorm/database.ex:19: Gorm.Database.handle_call/3
       test/gorm/database_test.ex:9: (test)

I don’t have line numbers, but I suspect it is failing on this line:

my_models = Accounts.Repo.all(User)

where is User defined?

You mean User schema right? or model?
Anyways I’ve alias both

Is it aliased in the module where it is called? (not the test module, the genserver one)?

Yes I did. I resolved that. But now I got the most interesting error


  1) test test (Gorm.DatabaseTest)
     test/gorm/database_test.ex:8
     ** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.349.0>.
     
     When using ownership, you must manage connections in one
     of the four ways:
     
     * By explicitly checking out a connection
     * By explicitly allowing a spawned process
     * By running the pool in shared mode
     * By using :caller option with allowed process
     
     The first two options require every new process to explicitly
     check a connection out or be allowed by calling checkout or
     allow respectively.
     
     The third option requires a {:shared, pid} mode to be set.
     If using shared mode in tests, make sure your tests are not
     async.
     
     The fourth option requires [caller: pid] to be used when
     checking out a connection from the pool. The caller process
     should already be allowed on a connection.
     
     If you are reading this error, it means you have not done one
     of the steps above or that the owner process has crashed.
     
     See Ecto.Adapters.SQL.Sandbox docs for more information.
     code: assert [] = Database.handle_call(:list, make_ref(), %{})
     stacktrace:
       (ecto_sql) lib/ecto/adapters/sql.ex:609: Ecto.Adapters.SQL.raise_sql_call_error/1
       (ecto_sql) lib/ecto/adapters/sql.ex:545: Ecto.Adapters.SQL.execute/5
       (ecto) lib/ecto/repo/queryable.ex:192: Ecto.Repo.Queryable.execute/4
       (ecto) lib/ecto/repo/queryable.ex:17: Ecto.Repo.Queryable.all/3
       (gorm) lib/gorm/database.ex:20: Gorm.Database.handle_call/3
       test/gorm/database_test.ex:9: (test)



Finished in 0.04 seconds
1 test, 1 failure

Look

Looks like the error message is pretty self-explanatory. Docs are here: https://hexdocs.pm/ecto_sql/Ecto.Adapters.SQL.Sandbox.html

1 Like

Can you elaborate on why you’e trying to do database access this way? Introducing a genserver to make all of the database calls will only slow things down, in addition to adding testing complexity.

3 Likes