DDD.Test (vicander v0.1.1)

Copy Markdown View Source

Helpers for testing an application built on the framework.

use ExUnit.Case
import DDD.Test

test "completing the last item finishes the list" do
  {:ok, list} = TodoList.complete_item(list, item.id)

  assert_event_emitted(list, ItemCompleted, item_id: item.id)
  refute_event_emitted(list, ListReopened)
end

test "a failure says why" do
  assert_error_code(TodoList.complete_item(list, item.id), :already_completed)
end

test "the handlers ran" do
  {:ok, _} = Commands.AddItem.call(...)
  drain_outbox()
  assert ... # the handlers' effects
end

Pending events are the ones an aggregate has emitted and not yet saved. Once a repository saves it they are in the outbox; drain_outbox/1 delivers them to the subscribed handlers.

Summary

Functions

Assert that a result is {:error, %DDD.Error{}} that has code (its own, or one of its violations'). Returns the error, so more can be asserted about it.

Assert that aggregate emitted an event of the event module, optionally with these field values. Returns the first matching event.

Deliver every event waiting in the outbox to the subscribed handlers, now, instead of waiting for the poller's timer. Needs the poller to be running (DDD.Supervisor starts it, with poller: [interval_ms: 600_000] to keep it from polling by itself in tests). Events that handlers produce while handling are delivered too. Returns how many events were delivered.

The events an aggregate has emitted and not yet saved.

Assert that aggregate did not emit such an event.

Functions

assert_error_code(other, code)

@spec assert_error_code(term(), atom()) :: DDD.Error.t()

Assert that a result is {:error, %DDD.Error{}} that has code (its own, or one of its violations'). Returns the error, so more can be asserted about it.

assert_event_emitted(aggregate, event, fields \\ [])

@spec assert_event_emitted(struct(), module(), keyword()) :: struct()

Assert that aggregate emitted an event of the event module, optionally with these field values. Returns the first matching event.

drain_outbox(max_rounds \\ 20)

@spec drain_outbox(non_neg_integer()) :: non_neg_integer()

Deliver every event waiting in the outbox to the subscribed handlers, now, instead of waiting for the poller's timer. Needs the poller to be running (DDD.Supervisor starts it, with poller: [interval_ms: 600_000] to keep it from polling by itself in tests). Events that handlers produce while handling are delivered too. Returns how many events were delivered.

emitted_events(map)

@spec emitted_events(struct()) :: [struct()]

The events an aggregate has emitted and not yet saved.

refute_event_emitted(aggregate, event, fields \\ [])

@spec refute_event_emitted(struct(), module(), keyword()) :: :ok

Assert that aggregate did not emit such an event.