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
Currently the RateLimiter component has time dependency hardcoded, with lot of microtime(true) calls everywhere making it unmockable and thus untestable.
Internally Symfony leverages the \Symfony\Bridge\PhpUnit\ClockMock::register to mock and test the component, but this is not a suitable solution for the component consumers.
Example
The Optimal solution would be to set for every class the ClockInterface dependency in the constructor, but of course this would be a BC Break; we can do it in the next major, but not now in v6.
A backward compatible workaround for v6 could be to have a dedicated clock registry that every RateLimiter class consumes, something like:
namespaceSymfony\Component\RateLimiter;
useSymfony\Component\Clock\ClockInterface;
useSymfony\Component\Clock\NativeClock;
/** * @deprecated Symfony v7 is going to have explicit ClockInterface dependency */finalclassRateLimiterClockRegistry
{
privatestaticClockInterface$clock;
publicstaticfunctionsetClock(ClockInterface$clock): void
{
self::$clock = $clock;
}
publicstaticfunctiongetClock(): ClockInterface
{
if (! isset(self::$clock)) {
self::$clock = newNativeClock();
}
returnself::$clock;
}
}
Internally Symfony leverages the \Symfony\Bridge\PhpUnit\ClockMock::register to mock and test the component, but this is not a suitable solution for the component consumers.
\Symfony\Bridge\PhpUnit\ClockMock::register it's not inside the rate limiter package.
A user shouldn't require another external package just to mock the rate limiter, especially if it leverages hacky eval calls and cleaner alternatives can be easily implemented.
Description
Currently the
RateLimiter
component has time dependency hardcoded, with lot ofmicrotime(true)
calls everywhere making it unmockable and thus untestable.Internally Symfony leverages the
\Symfony\Bridge\PhpUnit\ClockMock::register
to mock and test the component, but this is not a suitable solution for the component consumers.Example
The Optimal solution would be to set for every class the
ClockInterface
dependency in the constructor, but of course this would be a BC Break; we can do it in the next major, but not now inv6
.A backward compatible workaround for
v6
could be to have a dedicated clock registry that every RateLimiter class consumes, something like:Then all call can be edited to:
And the component become mockable by consumers as well.
I am willing to create the PR if this sounds good to the maintainers.
The text was updated successfully, but these errors were encountered: