phpspec / prophecy

Highly opinionated mocking framework for PHP 5.3+
MIT License
8.53k stars 241 forks source link

Object of class Exception could not be converted to int #584

Closed lucassabreu closed 1 year ago

lucassabreu commented 1 year ago
$ ./bin/phpunit --filter ExampleTest
PHPUnit 9.5.27 by Sebastian Bergmann and contributors.

E                                                                   1 / 1 (100%)

Time: 00:00.023, Memory: 30.00 MB

There was 1 error:

1) CoreTest\ExampleTest::testShouldRegisterException
ErrorException: Notice: Object of class Exception could not be converted to int

tests/CoreTest/ExampleTest.php:26

Example of testcase:

<?php

namespace CoreTest;

use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Psr\Log\LoggerInterface;

class ExampleTest extends TestCase
{
    use ProphecyTrait;

    public function testShouldRegisterException()
    {
        $logger = $this->prophesize(LoggerInterface::class);

        $logger->error(Argument::type('string'), Argument::allOf(
            Argument::withEntry('id', 10),
            Argument::withEntry('exception', new \Exception('wrong')),
        ))
            ->shouldBeCalled();

        $logger->reveal()->error('message', [
            'id' => 10,
            'exception' => new \Exception('wrong'),
            'other' => rand(0, 1000),
        ]);
    }
}

The error is thrown because the ExactValueToken checks if the value or argument maybe a object, and if only one of them is, it checks for a __toString in the object.

But PHP does not convert the object to string, before comparing it to a int|float.

When one of them (value or argument) is a object and the other is a int|float it needs to cast the object to string before comparing OR return false because they do not have the same type.

I already opened a PR to fix it: #583

ciaranmcnulty commented 1 year ago

Yikes that's a good find