Closed abeal-hottomali closed 3 years ago
One possible resolution to this.
// \Zenstruck\Messenger\Test\Transport\TestTransportFactory
private static $lastTransports = [];
public function createTransport(string $dsn, array $options, SerializerInterface $serializer): TransportInterface
{
$transport_options = $this->parseDsn($dsn);
if (array_key_exists($options['transport_name'], self::$lastTransports)) {
/* @var \Zenstruck\Messenger\Test\Transport\TestTransport $last_transport */
$last_transport = self::$lastTransports[$options['transport_name']];
// Port any options set on the last transport.
$last_transport_options = [
'intercept' => $last_transport->getIntercept(),
'catch_exceptions' => $last_transport->getCatchExceptions()
];
$transport_options = array_merge($transport_options, $last_transport_options);
}
$result = new TestTransport($options['transport_name'], $this->bus, $serializer, $transport_options);
self::$lastTransports[$options['transport_name']] = $result;
return $result;
}
// \Zenstruck\Messenger\Test\Transport\TestTransport
/**
* @return bool|mixed
*/
public function getIntercept(): bool
{
return $this->intercept;
}
/**
* @return bool|mixed
*/
public function getCatchExceptions(): bool
{
return $this->catchExceptions;
}
Thanks for the report @abeal-hottomali. #8 adds failing tests to demonstrate the problem. I'll work on a fix.
I tried this version, and I'm now running into a separate issue. With my default configuration
sync:
dsn: test://?intercept=false&catch_exceptions=false
I'm seeing the error:
"The \"kernel\" service is synthetic, it needs to be set at boot time before it can be used.",
When I change the configuration to be intercept:true
, the tests operate as expected (currently, the tests in question don't need what the messenger task accomplishes to complete successfully). I'm not sure what is going on. It seems like the change here might have had an impact, but I'm still digging to try to find out.
Ok, thanks, I'll look into this.
When does this error occur? When you call $this->messenger()
? If so, can you see if the kernel is booted before making this call (self::$booted
should === true
).
I've been pulled away into something else, but yes, I'll look and get back to you as soon as I'm able. I can tell you off the top of my head that the tests involved don't even use InteractsWithMessenger
.
For reference, this is my project's default messenger.yaml
:
framework:
messenger:
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
failure_transport: failed
transports:
# By default, messages are handled as soon as they are dispatched. If you want to
# handle a message asynchronously, you can configure a transport.
# A transport is capable of sending messages (e.g. to a queueing system) and then
# receiving them via a worker. Messenger supports multiple transports.
# See https://symfony.com/doc/current/messenger.html#transports-async-queued-messages
# Processed by the AMQP messenger transport asynchronously. Handlers
# sent here cannot be relied on for their return values immediately.
# This is by design.
# AMQP transport options can be found at
# https://symfony.com/doc/current/messenger.html#amqp-transport
async:
dsn: '%env(trim:resolve:MESSENGER_TRANSPORT_DSN)%'
options:
auto_setup: true
# Sync is explicitly spelled out even though it just specifies default values
# to allow changing message transports based on environment if necessary.
# https://symfony.com/doc/current/messenger.html#handling-messages-synchronously
sync:
dsn: 'sync://'
# Let doctrine handle the failed message queue for now.
# (This may be better done by amqp - revisit).
failed:
dsn: 'doctrine://default?queue_name=failed'
options:
auto_setup: true
And this is for the testing environment:
framework:
messenger:
transports:
# Process async transport using zenstruck test transport. This allows us
# to ensure messages were fired upon certain events, and optionally still
# process them.
# Uses zenstruck messenger transport for testing sent messages:
# https://github.com/zenstruck/messenger-test#queue-assertions
async:
dsn: test://
# Use the test transport for sync messages as well, so we have the option to
# block in a given integration test, and confirm a message was sent, or just
# let the message be processed normally.
sync:
dsn: test://?intercept=false&catch_exceptions=false
So do your tests using the async transport work fine?
@OskarStark has discovered, I think, the same problem as you, I'm tracking in #9.
Thank you, I'll be back on this tomorrow and will give it a go!
-- Aron Beal Developer Team Lead @.***
Hot Tomali Communications 1441 East Pender Street Vancouver BC V5L 1V7 P 604.893.8347 P 604.893.8346
www.hottomali.com
On May 14, 2021, 3:30 PM -0700, Kevin Bond @.***>, wrote:
This should be fixed in v0.3.1 but let me know if it isn't. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.
Confirmed that this is working for me ok in v0.3.1, thanks!
Thanks for the update!
Noticed this recently when running a longer test: About halfway through, the transport had to be reconstructed as a service. When that happened, the values from the config were used (
config/packages/test/messenger.yaml
), and the call tointercept()
earlier in the test was no longer honoured.My configuration value for the transport in question:
I'm trying to change this transport to intercept = true for the length of a given test. It works initially, but the value resets when the service is regenerated. See also the options passed in
\Zenstruck\Messenger\Test\Transport\TestTransportFactory::createTransport
, and the options expected in\Zenstruck\Messenger\Test\Transport\TestTransport::__construct