2

ClockMock is a very useful tool for creating time sensitive tests e.g. if a date is in past A should happen, if it is in the future B should happen.

ClockMock is a part of the phunit-bridge, which worked fine with Phpunit 8. Now is the year 2025 and the current version of Phpunit is 11.

This Symfony docs issue (#20344 (github.com)) suggests to me that this feature should work now also with Phpunit version 10 or higher provided you use phpunit-bridge 7.2

My project configuration:

  • symfony: 6.4
  • php: 8.2
  • phpunit/phpunit: 10.5.41
  • symfony/phpunit-bridge: 7.2.0

The documentation (https://symfony.com/doc/6.4/components/phpunit_bridge.html#clock-mocking) says that I have to activate a listener in my phpunit.xml file, but Phpunit 10+ doesn't know this option any longer:

<listeners>
    <listener class="\Symfony\Bridge\PhpUnit\SymfonyTestsListener"/>
</listeners>

So I removed the listener from my XML file.

In my test the code is the following:

class CompanyNameHelperTest extends TestCase
{
    public function testGetCompanyNameByIdPast(): void
    {
        ClockMock::register(CompanyNameHelper::class);
        ClockMock::withClockMock(true);
        ClockMock::withClockMock(strtotime('2018-11-05 01:00:00'));
        $myDate = (new DateTimeImmutable(date('Y-m-d H:m:s')));
        $companyId = 1;
        $this->assertEquals(
            'ACME KG, Hamburg',
            CompanyNameHelper::getCompanyNameById($companyId, $myDate)
        );
        ClockMock::withClockMock(false);
    }

Which results in a failing test, because the date from the past is not used and the current system time instead.

What is the correct way to use ClockMock in Phpunit version 10 and higher?

1 Answer 1

3

This is perhaps yet undocumented (#20344):

    <extensions>
        <bootstrap class="Symfony\Bridge\PhpUnit\SymfonyExtension">
            <parameter name="clock-mock-namespaces" value="App" />
            <parameter name="dns-mock-namespaces" value="App" />
        </bootstrap>
    </extensions>

Adding the extension with the features you'd like per their parameters shall be it.

More details can be found in the actual change-set in symfony/symfony #58467 (github.com) and information in [PHPUnit bridge] Support for PHPUnit 11.1+ #49069 (github.com) for the rationale to use Phpunit 11.

As Calamity Jane mentioned in a comment:

if you use the annotation, you can even upgrade to phpunit 11 #[Group('time-sensitive')]

And the feature brought to you by xabbuh - thanks!

Sign up to request clarification or add additional context in comments.

7 Comments

If I put the listener back in the xml file the test still fails, but additionalle I get this: There was 1 PHPUnit test runner warning: 1) Test results may not be as expected because the XML configuration file did not pass validation: Line 28: - Element 'listeners': This element is not expected.
Also thetest still fails, if I addtionally add the annotation: @group time-sensitive
This somehow looks to me that the bridge does not take care of that which is suspicous. Are you executing phpunit from the bridge or directly?
I execute it directly. like this $ bin/phpunit tests/Helper/CompanyNameHelperTest.php which worked fine with the lower phpunit versions. If I execute simple-phpunit it installs phpunit 9.6 to replace phpunit 10, which is no solution.
if you use the annotation, you can even upgrade to phpunit 11 #[Group('time-sensitive')]
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.