I am trying to verify membership in an Elixir association.
Say I have two models: Product and ProductType. Products are related to the type of product.
defmodule Store.Product do use Store.Web, :model schema "products" do field :name, :string belongs_to :type, Store.ProductType, foreign_key: :product_type_id timestamps end @required_fields ~w(name product_type_id) @optional_fields ~w() def changeset(model, params \\ :empty) do model |> cast(params, @required_fields, @optional_fields) end end defmodule Store.ProductType do use Store.Web, :model schema "product_types" do field :name, :string timestamps end @required_fields ~w(name) @optional_fields ~w() def changeset(model, params \\ :empty) do model |> cast(params, @required_fields, @optional_fields) end end
Here is what I have in my test file:
defmodule Store.ProductTest do use Store.ModelCase alias Store.Repo alias Store.Product alias Store.ProductType @valid_attrs %{ name: "pickles", product_type_id: 42, } @invalid_attrs %{} test "product type relationship" do product_type_changeset = ProductType.changeset( %ProductType{}, %{name: "Foo"} ) product_type = Repo.insert!(product_type_changeset) product_changeset = Product.changeset( %Product{}, %{@valid_attrs | product_type_id: product_type.id} ) product = Repo.insert!(product_changeset) product = Product |> Repo.get(product.id) |> Repo.preload(:type) assert product_type == product.type end end
I basically create a product type, create a product, retrieve the product from the database and verify that the type is the same as the one I created.
Is this a smart approach?
EDIT
For posterity, this is a cleaner test without using change sets:
test "belongs to product type" do product_type = Repo.insert!(%ProductType{}) product = Repo.insert!(%Product{product_type_id: product_type.id}) product = Product |> Repo.get(product.id) |> Repo.preload(:type) assert product_type == product.type end
To test this connection, you can significantly refuse castings and validations.