createServiceWithoutConstructor(); $method = new ReflectionClass(LeaveBalanceComputationService::class)->getMethod('computeAccruedDays'); $result = $method->invoke( $service, 25.0, 25.0 / 12.0, new DateTimeImmutable('2025-06-10'), new DateTimeImmutable('2026-02-28') ); self::assertEqualsWithDelta(18.125, $result, 0.0001); } public function testComputeAccruedDaysTotalMatchesAlainCase(): void { $service = $this->createServiceWithoutConstructor(); $method = new ReflectionClass(LeaveBalanceComputationService::class)->getMethod('computeAccruedDays'); $days = $method->invoke( $service, 25.0, 25.0 / 12.0, new DateTimeImmutable('2025-06-10'), new DateTimeImmutable('2026-02-28') ); $saturdays = $method->invoke( $service, 5.0, 5.0 / 12.0, new DateTimeImmutable('2025-06-10'), new DateTimeImmutable('2026-02-28') ); self::assertEqualsWithDelta(21.75, $days + $saturdays, 0.0001); } public function testComputeAccruedDaysIncludesLastDayOfMonthDespiteTimeComponents(): void { $service = $this->createServiceWithoutConstructor(); $method = new ReflectionClass(LeaveBalanceComputationService::class)->getMethod('computeAccruedDays'); $result = $method->invoke( $service, 25.0, 25.0 / 12.0, new DateTimeImmutable('2026-02-01 12:50:18'), new DateTimeImmutable('2026-02-28 00:00:00') ); self::assertEqualsWithDelta(25.0 / 12.0, $result, 0.0001); } private function createServiceWithoutConstructor(): LeaveBalanceComputationService { $rc = new ReflectionClass(LeaveBalanceComputationService::class); $service = $rc->newInstanceWithoutConstructor(); $prop = $rc->getProperty('suspensionDaysCalculator'); $prop->setValue($service, new SuspensionDaysCalculator()); return $service; } }