I have extended PHP Exception with my own to add additional data:
class MyException extends Exception {
public $foo = [];
public function __construct($message = '', $data = null, $code = 0) {
$this->foo = $data;
paret::__construct($message, $code);
}
}
When doing normal requests these errors logs correctly and I do not want to add any additional content to $this->message.
When running test I can throw it:
if (!$this->save()) {
throw new MyException('Internal Server Error', ['log' => 'missing data'], 500);
}
and PHPUnit will output:
MyException: Internal Server Error
I want:
MyExeption: Internal Server Error; {"log": "missing data"}
How to extend PHPUnit to be able to show $myException->foo along with error message?
Sample code:
<?php
class SampleTest extends CTestCase
{
public function testIndex()
{
$this->assertTrue($this->save());
}
protected function save()
{
$model = new Orders();
$model->addError('id', 'ID is Required');
if (!$model->validate()) {
throw new HttpApiModelException(500, 'Failed to save', $model);
}
return true;
}
}
Executed with command common/vendor/bin/phpunit --configuration tests/phpunit.xml --verbose tests/functional/SampleTest.php
And output:

I am not sure if this is the best option but you could implement test results printer, smth like:
<?php
namespace Tests;
use PHPUnit\TextUI\ResultPrinter;
class TestPrinter extends ResultPrinter
{
protected function printDefect(\PHPUnit\Framework\TestFailure $defect, $count)
{
$this->printDefectHeader($defect, $count);
$ex = $defect->thrownException();
// you can do whatever you need here,
// like check exception type, etc,
// printing just line number here
$this->write('Line #' . $ex->getLine() . "\n");
$this->printDefectTrace($defect);
}
}
and register as a printer to be used (assume xml config but could be done via command line as well):
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
printerClass="Tests\TestPrinter"
>
<!-- note printerClass attribute above -->
</phpunit>
Doing so, you would get output looking similar with:
There was 1 error:
1) Tests\SomeTest::testStuff
Line #16
LogicException: whatever
(I just made a simple test doing throw new \LogicException('whatever');)
So if you need this data to be printed everytime when you are running tests but not when it's on production then why not to extend the base Exception class and to check if you are under test environment then to concatenate the message and the data. And then all of your custom exceptions to extend this new Exception class.
class BaseException extends Exception {
public function __construct($message = '', $data = null, $code = 0) {
if (env('ENVIRONMENT') === 'test') {
$message .= ' ' . json_encode($data);
}
paret::__construct($message, $code);
}
}
But this implementation will require to change your MyException class to call the parent constructor with this data.
Instead of this
paret::__construct($message, $code);
Now you are going to have this
paret::__construct($message, $data, $code);
And also to extend the new BaseException class to these exception which you want to have this functionality
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With