You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Following the unit testing matrix outlined by Sandi Metz in her talk The Magic Tricks of Testing), to test side affects in an event handler you could use a mock to verify the expected external command is called. You don’t test the actual side effects when unit testing the handler, but you do verify they are called.
You can either call the event handler’s handle/2 function directly or cause the event to be produced (via command dispatch or appending the event to a stream) and afterwards verify the side-affect was called.
defmoduleCustomerPromotionTestdouseExUnit.CaseimportMoxsetup:verify_on_exit!test"`send_promotion/1` is called by promotion handler"doreply_to=self()NotificationMock.expect(:send_promotion,customer_id->send(reply_to,{:send_promotion,customer_id}):okend)# Start handler process and dispatch command to produce trigger eventstart_supervised!(CustomerPromotionHandler):ok=MyApp.dispatch(command)assert_receive{:send_promotion,^expected_customer_id}# Or call handler directly with an event (doesn’t require the handler process to be started):ok=CustomerPromotionHandler.handle(event,metadata)endend
With Mox you must define a behaviour which can then be mocked or stubbed at runtime.
It's often useful to define a facade module for the behaviour which can substitute the mock at runtime or compile time. In this example the implementation module (real or mock) is determined at compile time from application config:
defmoduleNotificationdo@behaviourNotificationBehaviour@implementationApplication.get_env(:myapp,__MODULE__,Notification.DefaultImpl)defdelegatesend_promotion(customer_id),to: @implementationenddefmoduleNotification.DefaultImpldo@behaviourNotificationBehaviourdefsend_promotion(customer_id)do# Actual implementation goes here ...endend
With the above setup the Notification.DefaultImpl module containing the actual implementation will be used in non-test environments and the mock will be used during tests. This allows the side effect call (send_promotion/1) to be tested, without actually causing the side effect. It also allows you to easily test failures by returning a different response from the mock call (e.g. {:error, failed_to_send}).
To test the event handler and its side effects you could use an integration style test and would replace the side effect module mock with the actual implementation. You could use Mox’s stub_with(NotificationMock, Notification.DefaultImpl) which forwards all calls to the mock to the actual implementation. This ensures the contract is valid between the caller and the target module.
The text was updated successfully, but these errors were encountered:
How to test event handler side effects.
Following the unit testing matrix outlined by Sandi Metz in her talk The Magic Tricks of Testing), to test side affects in an event handler you could use a mock to verify the expected external command is called. You don’t test the actual side effects when unit testing the handler, but you do verify they are called.
You can either call the event handler’s
handle/2
function directly or cause the event to be produced (via command dispatch or appending the event to a stream) and afterwards verify the side-affect was called.With Mox you must define a behaviour which can then be mocked or stubbed at runtime.
It's often useful to define a facade module for the behaviour which can substitute the mock at runtime or compile time. In this example the implementation module (real or mock) is determined at compile time from application config:
The mock must be defined in the test support:
Then configured for the test environment:
With the above setup the
Notification.DefaultImpl
module containing the actual implementation will be used in non-test environments and the mock will be used during tests. This allows the side effect call (send_promotion/1
) to be tested, without actually causing the side effect. It also allows you to easily test failures by returning a different response from the mock call (e.g.{:error, failed_to_send}
).To test the event handler and its side effects you could use an integration style test and would replace the side effect module mock with the actual implementation. You could use Mox’s
stub_with(NotificationMock, Notification.DefaultImpl)
which forwards all calls to the mock to the actual implementation. This ensures the contract is valid between the caller and the target module.The text was updated successfully, but these errors were encountered: