Shorthand for built-in transformations (`cast`)

Again, the code under test is, so far, pretty trivial:

  embedded_schema do
    field :age, :integer
    field :date, :date
  end

  def changeset(struct, params) do
    struct
    |> cast(params, [:age, :date])
    |> validate_required([:age, :date])
  end

Nothing is done with the input data except Ecto's built in string-to-integer and string-to-date transformations.

Most schemas are more complicated but–importantly–they are built from parts that aren't. Within more complicated schemas lurk fields just as simple as :age or :date. Again, tests should be able to take advantage of stereotyped code. To that end, see line 4:

  def create_test_data do
    start(...)

    field_transformations(as_cast: [:age, :date]) |> 

    category(                                         :success,
      ok: [
        params(age: 1, date:   "2001-01-01"),
      ]) |> 

Line 4 declares that, in the case of successful validation, these two fields will have the values that Changeset.cast gives them, so there's no need for an explicit changeset clause in the :ok example.

This is implemented by actually calling Changeset.cast, not by assuming that the params as given are in the intended form. Generated test code takes advantage of the same libraries that product code should be using.

as_cast also works with validation failures. Here's an example that narrows in on what a bad date parameter looks like:

    category(                                 :validation_failure,
      bad_date: [
        params_like(:ok, except: [date: "2001-1-1"]),
      ])

Again, no changeset clause is required. When the test runner calls Changeset.cast, it will get a changeset with no changes for date and an error message associated with that field. It will check that the function under test (Basic.changeset) produces what Changeset.cast does.

That might seem pointless: aren't you checking that cast does what cast does?

That's roughly true. There aren't very many bugs involving such fields that wouldn't be caught by tests written for other purposes. Quite often, I wouldn't be tempted to write explicit assertions about those fields. On the other hand, if it's as easy as typing the field name once after as_cast:, why not?

Other field transformations are more useful.

Last updated