如何PHPUnit测试一个没有返回值的方法?

Mat*_*bst 13 php phpunit unit-testing

我正在尝试从我编写的以下类中测试方法(函数比显示的更多,基本上,每个函数都是_*()方法):

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));
  }

  ...

}
Run Code Online (Sandbox Code Playgroud)

当我测试方法是否在无效输入上抛出异常时,它的效果很好!但是,当我测试方法是否按预期工作时,PHPUnit会抱怨因为我在测试中没有断言.具体错误是:

# RISKY This test did not perform any assertions
Run Code Online (Sandbox Code Playgroud)

但是,我没有任何价值可以断言,所以我不知道如何克服这一点.

我已经阅读了一些关于测试静态方法的内容,但这似乎主要涵盖了静态方法之间的依赖关系.此外,即使是非静态方法也没有返回值,那么,如何解决这个问题呢?

供参考,我的测试代码:

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.");
  }
}
Run Code Online (Sandbox Code Playgroud)

Ren*_*gen 9

为了防止关于断言的警告,您可以使用@doesNotPerformAssertions文档中解释的注释:https : //phpunit.de/manual/current/en/appendixes.annotations.html#idp1585440

或者,如果您更喜欢代码而不是注释: $this->doesNotPerformAssertions();

  • 不错的答案,但应该是 `expectNotToPerformAssertions`,而不是 `doesNotPerformAssertions`,因为首先只返回当前值。[github](https://github.com/sebastianbergmann/phpunit/blob/64d377cc488cd3707f34f46266c8d22e21f1da06/src/Framework/TestCase.php#L617) (5认同)

Mat*_*bst 8

我想到的一个解决方案如下,基于PHPUnit 第 2 章的示例 2.12。对我来说,这感觉有点老套,但这是迄今为止我发现的最好的。另外,根据PHPUnit Gitub 问题讨论,似乎还有其他几个人想要此功能,但没有计划实现它。

更改testIsStringNoExceptionArgumentValid()为以下内容:

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

    $this->assertTrue(TRUE);
  }
Run Code Online (Sandbox Code Playgroud)

  • 您不需要 try/catch 位。不需要fail(),异常会做到这一点。 (2认同)

小智 5

使用assertNull测试void函数:

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

  • 尝试使用 void 函数的返回值将(正确地)在许多 linter 中被标记。 (7认同)