Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Time Mock Bundle Laravel Package

acts/time-mock-bundle

Symfony bundle for mocking and controlling time in tests and development. Freeze, fast-forward, and reset “now” to make time-dependent code deterministic, simplify assertions, and avoid flaky tests across DateTime/Clock usage.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require acts/time-mock-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Acts\TimeMockBundle\ActsTimeMockBundle::class => ['all' => true],
    ];
    
  2. Basic Usage Register a mock time provider in your test bootstrap (e.g., tests/TestCase.php):

    use Acts\TimeMockBundle\TimeMock;
    
    class TestCase extends \PHPUnit\Framework\TestCase
    {
        protected function setUp(): void
        {
            TimeMock::setTime('2023-01-01 12:00:00');
        }
    
        protected function tearDown(): void
        {
            TimeMock::reset();
        }
    }
    
  3. First Use Case Test time-sensitive logic (e.g., a User::isActive() method that checks last login):

    public function testUserActivity()
    {
        $user = new User();
        $user->lastLogin = '2023-01-01 11:00:00'; // Set via mock
        $this->assertTrue($user->isActive()); // Logic now uses mocked time
    }
    

Implementation Patterns

Core Workflow

  1. Mocking Time Globally Override time functions (now(), Carbon::now(), etc.) in tests:

    TimeMock::setTime('2023-01-01 12:00:00');
    $this->assertEquals('2023-01-01 12:00:00', now()->toDateTimeString());
    
  2. Time Travel Increment time dynamically:

    TimeMock::setTime('2023-01-01 12:00:00');
    TimeMock::addHours(2); // Now returns 14:00
    
  3. Integration with Carbon Works seamlessly with Laravel’s Carbon:

    $mockedTime = Carbon::parse('2023-01-01 12:00:00');
    TimeMock::setTime($mockedTime);
    

Advanced Patterns

  • Scoped Mocking Useful for nested tests:

    TimeMock::setTime('2023-01-01 12:00:00');
    $this->testScopedTime(); // Uses mocked time
    TimeMock::reset(); // Restore original time
    
  • Freezing Time Pause time for deterministic tests:

    TimeMock::freeze();
    // All time calls return the same value until unfrozen
    TimeMock::unfreeze();
    
  • Custom Providers Extend functionality for specific needs:

    TimeMock::setProvider(new CustomTimeProvider());
    

Gotchas and Tips

Pitfalls

  1. Global State Mocking time affects all tests unless explicitly reset. Use tearDown() to avoid leaks:

    protected function tearDown(): void
    {
        TimeMock::reset(); // Critical!
    }
    
  2. Time Zone Confusion Ensure mocked time respects your app’s timezone (e.g., config/app.php):

    TimeMock::setTime('2023-01-01 12:00:00', 'UTC'); // Explicit timezone
    
  3. Static Method Dependencies Some libraries (e.g., DateTime::createFromFormat()) may bypass the mock. Use Carbon or wrap calls:

    $mocked = TimeMock::now(); // Use provided helper
    

Debugging Tips

  • Verify Mocked Time Log the current mocked time:

    $this->assertEquals('2023-01-01 12:00:00', TimeMock::getTime());
    
  • Check for Resets If tests fail unexpectedly, confirm TimeMock::reset() is called.

Extension Points

  1. Custom Time Providers Implement Acts\TimeMockBundle\Provider\TimeProviderInterface for bespoke logic:

    class CustomProvider implements TimeProviderInterface
    {
        public function getTime(): \DateTimeInterface
        {
            return new \DateTime('now', new \DateTimeZone('America/New_York'));
        }
    }
    
  2. Override Default Bindings Replace Laravel’s now() binding in AppServiceProvider:

    use Acts\TimeMockBundle\TimeMock;
    
    public function register()
    {
        $this->app->singleton(\Illuminate\Contracts\Foundation\Application::class, function () {
            $app = new Application();
            $app->bind('now', function () {
                return TimeMock::now();
            });
            return $app;
        });
    }
    
  3. Mocking in CI/CD Ensure CI environments don’t interfere with mocked time by resetting early:

    beforeApplication($app) {
        TimeMock::reset();
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle