The original post was regarding generating functions in the context. I would still like some tests in place, which tend to be even more repetitive and time-consuming than the context functions. Thus, a corresponding CrudTest module has been added. The idea here is, to the extent possible, match the API of the context function macros. The basic flow for each is to insert a factory/factories for the given resource, call the corresponding function, and then assert the results. As in the case of the context functions, if I need to add, change, or test these functions in ANY other way, I should just write out the tests and not use the macro. All of these macros generate a describe block with the function name and then include any number of test cases that make sense for the context function.
For example, CrudTest.list(@resource) will insert a few unit records and then assert that list_units() returns those records. Factory records are also created for various associations as needed in get_for!, preload, join, filter_by_*, etc. For most data types, order_by will generate data and assert the correct ordering.
The main difference is that the context function macros create, update, and change take a changeset as the second argument, whereas the test macros take actual test data (as a map or function) as that argument.
Most of the tests cover what I usually need for each case. The exception is in create and update. Those are purely smoke tests that ensure that passing valid data can create and update a record. In most cases, I will want to write out tests to cover error cases and such.
Factory names are based off the resource/association schema name. In cases where that does not match for the resource a factory option can be passed to config (ex. factory: :user). In case where associations do not match, an association_factories option can be passed to config (ex. [creator: :user, property: :building]).
Here is an example of tests for the corresponding functions in the original post above.
defmodule MyApp.Inventory.UnitTest do
use MyApp.DataCase
alias MyApp.Inventory.Unit
@resource CrudTest.config(Unit, Repo)
# Common CRUD function tests
CrudTest.list(@resource)
CrudTest.get!(@resource)
CrudTest.get(@resource)
CrudTest.new(@resource)
CrudTest.create(@resource, %{name: "My Place"})
CrudTest.change(@resource, %{name: "My Place"})
CrudTest.update(@resource, %{name: "My Place"})
CrudTest.delete(@resource)
# CRUD helper tests
CrudTest.paginate(@resource)
CrudTest.get_for!(@resource, :network)
CrudTest.get_for(@resource, :network)
CrudTest.get_by_attr!(@resource, :name)
CrudTest.get_by_attr(@resource, :name)
CrudTest.preload(@resource, :property)
CrudTest.join(@resource, :property)
CrudTest.filter_by_one(@resource, :property)
CrudTest.filter_by_one_or_many(@resource, :unit_type)
CrudTest.order_by(@resource, :name, :desc)
end






















