-
Notifications
You must be signed in to change notification settings - Fork 1
Description
How can I test a read model projector so that tests wait until events have been projected?
Using Elixir telemetry and the after_update/3 callback function
Commanded Ecto projections provides an after_update/3 callback function. This gets called after each event is projected. You can use the funtion to publish a notification whenever an event is projected, including the database changes.
Here’s an example using the Elixir/Erlang telemetry library.
In the projector:
def after_update(event, metadata, changes) do
:telemetry.execute(
[:projector],
%{system_time: System.system_time()},
%{event: event, metadata: metadata, changes: changes, projector: __MODULE__}
)
endIn a test:
setup do
reply_to = self()
:ok =
:telemetry.attach(
"test-handler",
[:projector],
fn event, measurements, metadata, reply_to ->
send(reply_to, {:telemetry, event, measurements, metadata})
end,
self()
)
endUsage in test to wait:
assert_receive {:telemetry, [:projector], _measurements, %{event: event, metadata: metadata, changes: changes}}This approach will ensure the test blocks until the projector has done its work and then you can run either use the changes from the Ecto.Multi or run a query to verify the database changes. You can also use pattern matching on the event from the telemetry metadata to wait for a particular event type.
The performance impact at runtime is negligible if there are no handlers attached to a telemetry event.