Matthew Herbst
Matthew Herbst

Reputation: 31973

How to PHPUnit test a method with no return value?

I am trying to test methods from the following class I have written (there are more functions than what is shown, basically, one function for each is_*() method):

class Validate {
  private static $initialized = false;

  /**
  * Construct won't be called inside this class and is uncallable from the outside. This prevents
  * instantiating this class. This is by purpose, because we want a static class.
  */
  private function __construct() {}

  /**
  * If needed, allows the class to initialize itself
  */
  private static function initialize()
  {
    if(self::$initialized) {
      return;
    } else {
      self::$initialized = true;
      //Set any other class static variables here
    }
  }

  ...

  public static function isString($string) {
    self::initialize();
    if(!is_string($string)) throw new InvalidArgumentException('Expected a string but found ' . gettype($string));
  }

  ...

}

When I test if the methods throw an exception on invalid input, it works great! However, when I test if the method works as expected, PHPUnit complains because I have no assert in the test. The specific error is:

# RISKY This test did not perform any assertions

However, I don't have any value to assert against so I'm not sure how to overcome this.

I've read some about testing static methods, but that mostly seems to cover dependencies between static methods. Further, even non-static methods could have no return value, so, how to fix this?

For reference, my test code:

class ValidateTest extends PHPUnit_Framework_TestCase {
  /**
  * @covers ../data/objects/Validate::isString
  * @expectedException InvalidArgumentException
  */
  public function testIsStringThrowsExceptionArgumentInvalid() {
    Validate::isString(NULL);
  }

  /**
  * @covers ../data/objects/Validate::isString
  */
  public function testIsStringNoExceptionArgumentValid() {
    Validate::isString("I am a string.");
  }
}

Upvotes: 24

Views: 39559

Answers (4)

Real Dreams
Real Dreams

Reputation: 18010

If you want to test a void function you only need to run it without any assertion. If it there is any issue it will throw an exception and test will fails. No need to put $this->assertTrue(TRUE); as you are not running an assertion and having assertions is not required to test your code.

You will get a message like


Time: 7.39 seconds, Memory: 16.00 MB

OK (1 test, 0 assertions)
Process finished with exit code 0

Upvotes: 1

Matthew Herbst
Matthew Herbst

Reputation: 31973

One solution I have come upon is the following, based on example 2.12 from chapter 2 of PHPUnit. It feels a little hacky to me, but it's the best I've found so far. Also, based on this PHPUnit Gitub issue discussion, it seems several other people want this feature but that there are no plans to implement it.

Change testIsStringNoExceptionArgumentValid() to the following:

  /**
  * @covers ../data/objects/Validate::isString
  */
  public function testIsStringNoExceptionArgumentValid() {
    try {
      Validate::isString("I am a string.");
    } catch (InvalidArgumentException $notExpected) {
      $this->fail();
    }

    $this->assertTrue(TRUE);
  }

Upvotes: 8

Rene Terstegen
Rene Terstegen

Reputation: 8046

To prevent the warning about the assertions you can use the @doesNotPerformAssertions annotation as explained in the documentation: https://phpunit.de/manual/current/en/appendixes.annotations.html#idp1585440

Or if you prefer code over annotation: $this->doesNotPerformAssertions();

Upvotes: 10

User5678015
User5678015

Reputation: 369

Test void function with assertNull:

    /**
     * @covers ../data/objects/Validate::isString
     */
    public function testIsStringNoExceptionArgumentValid() {
         $this->assertNull( Validate::isString("I am a string.") );
    }

Upvotes: 10

Related Questions