I’m refactoring a legacy PHP codebase, and that includes writing new tests. While doing that, I found a class method that accepts only a predetermined set of values, and refuses any other value by throwing an exception. Below is a simplified representation of this class:
<?php
class MyClass
{
protected $value;
public function setValue($value)
{
if (in_array($value, ['foo', 'bar'])) {
$this->value = $value;
return $this;
}
throw new RuntimeException("{$value} is not a valid value.");
}
}
Promptly, I wrote a test to check if the method was filtering out invalid input values:
<?php
use PHPUnit\Framework\TestCase;
class MyTestCase extends TestCase
{
protected $instance;
public function setUp()
{
$this->instance = new MyClass();
}
public function testSetValueRefusesBadInput()
{
$this->expectException(RuntimeException::class);
$this->instance->setValue('baz');
}
}
Easy peasy.
But what if the method is not handling valid input values correctly? Since the method accepts only a small set of values, we could test all of them. However, PHPUnit 6 doesn’t have a doNotExpectException
assertion, nor does it allow a test without an assertion.
We can easily overcome these limitations by adding an assertion to the end of the test ($this->assertTrue(true)
) or by increasing the assertion count ($this->addToAssertionCount(1)
). If the MyClass::setValue
method implementation is incorrect, an exception will be thrown, otherwise, the assertion will be accounted for and PHPUnit will not “complain” about the test.
<?php
use PHPUnit\Framework\TestCase;
class MyTestCase extends TestCase
{
protected $instance;
public function setUp()
{
$this->instance = new MyClass();
}
public function testSomethingWorks()
{
$this->instance->setValue('bar');
$this->addToAssertionCount(1);
}
public function testAnotherThingWorks()
{
$this->instance->setValue('foo');
$this->assertTrue(true);
}
}