这是一个最小的 phoenix 应用程序,它GenServer
在应用程序管理程序中启动,使用:shared
模式进行数据库交互。
应用模块:
defmodule TestGenServers.Application do
use Application
def start(_type, _args) do
import Supervisor.Spec
children = [
supervisor(TestGenServers.Repo, []),
supervisor(TestGenServers.Web.Endpoint, []),
worker(TestGenServers.MyServer, [])
]
opts = [strategy: :one_for_one, name: TestGenServers.Supervisor]
Supervisor.start_link(children, opts)
end
end
产品模块:
defmodule TestGenServers.Model.Product do
use Ecto.Schema
import Ecto.Changeset
alias TestGenServers.Model.Product
schema "model_products" do
field :name, :string
timestamps()
end
@doc false
def changeset(%Product{} = product, attrs) do
product
|> cast(attrs, [:name])
|> validate_required([:name])
end
end
GenServer 模块:
defmodule TestGenServers.MyServer do
use GenServer
alias TestGenServers.Repo
def start_link() do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def handle_call({:get_product, id}, _caller, state) do
{:reply, TestGenServers.Repo.get(TestGenServers.Model.Product, id), state}
end
end
测试模块:
defmodule TestGenServers.TestMyServer do
use TestGenServers.DataCase
setup do
product = Repo.insert!(%TestGenServers.Model.Product{name: "widget123"})
%{product_id: product.id}
end
test "talk to gen server", %{product_id: id} do
assert %{id: ^id, name: "widget123"} = GenServer.call(TestGenServers.MyServer, {:get_product, id})
end
end
数据案例模块
defmodule TestGenServers.DataCase do
use ExUnit.CaseTemplate
using do
quote do
alias TestGenServers.Repo
import TestGenServers.DataCase
end
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(TestGenServers.Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(TestGenServers.Repo, {:shared, self()})
end
:ok
end
end
测试助手:
ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(TestGenServers.Repo, :manual)