Testing Asynchronous Messaging
Testing asynchronous communication in PHP
When your code becomes asynchronous, sending Command is not enough to verify full flow.
Your message will land in pollable message channel (queue
) awaiting for consumption.
This requires executing your consumer in order to test full flow.
Ecotone
provides full support for testing your asynchronous messaging architecture
.
Example Asynchronous Handler
As an example, let's imagine scenario, where after placing order we want to send notification asynchronously.
Running code Synchronously
By default all the asynchronous code will run synchronously. This simplifies the tested code and speed ups your test suite.
Running Asynchronous Consumer
Ecotone provides In Memory Pollable Channels
which can replace real implementation for testing purposes.
Enable asynchronous processing - We enable asynchronous processing and provide Message Channel to poll from. Message Channel can be Real (SQS, RabbitMQ, Dbal etc) or In Memory one
Run - This runs the the consumer with given PollingMetadata
Assert - We assert the state after consumer has exited
In above example we are running consumer within same process as test.
You may run consumer from separate process like this: (example for symfony):
php bin/console ecotone:run notifications --handledMessageLimit=1 --executionTimeLimit=100 --stopOnFailure
However running consumer as separate process is not advised, as it requires booting separate process
which slows test suite, and due to lack ofshared memory
does not allow for using In Memory implementations.
Default Message Channels
For testing with In Memory Channels, we can omit providing specific implementation. Ecotone will deliver an default In Memory Message Channels for us:
Polling Metadata
By default Ecotone will optimize for your test scenario:
If real Message Channel like RabbitMQ, SQS, Redis will be used in test, then Message Consumer will be running up to 100ms and will stop on error.
If In Memory Channel will be used, then Message Consumer will be running till it fetches all Messages or error will happen.
The above default configuration ensures, tests will be kept stable and will run finish quickly.
However if in case of need this behaviour can be customized by providing ExecutionPollingMetadata
.
Testing Serialization
To test serialization we may fetch Message directly from the Channel and verify it's payload.
We can enable serialization on this channel for given
Media Type
. In this case, we say serialize tojson
all message going throughnotifications
.We pull and verify messages sent to
notifications
channel, if their were sent injson
format
By default In Memory Queue Channel will do the serialization to PHP native serialization or your default Serialization if defined. This way it works in similar way to your production Queue Channels.
If you don't want to use serialization however, you may set type to conversionMediaType: MediaType::createApplicationXPHP()
Testing Delayed Messages
Our Handlers may be delayed in time and we may want to run peform few actions and then release the message, to verify production like flow.
The default behaviour for In Memory Channels is to ignore delays. By setting
second parameter
totrue
we are registering In Memory Channel that will be aware of delays.We are releasing messages that awaits for 60 seconds or less.
Delaying to given date
If we delay to given point in time, then we can use date time for releasing this message.
Dropping all messages coming to given channel
In some scenarios, you may just want to turn off given channel, because you're not interested in messages that goes through it.
By registering
nullable channel
, we make use that all messages that will go to given channel will be dropped.
Last updated