如何编写自定义PHPUnit断言,其行为类似于内置断言?

mjs*_*mjs 6 phpunit assertion

我怎样才能编写一个自定义断言,就像assertFoo($expected, $actual)错误"堆栈跟踪"的内置断言一样?

我目前定义了以下方法(在扩展的类中PHPUnit_Framework_TestCase):

public static function assertFoo($expected, $actual) {
    self::assertEquals($expected, $actual); 
}
Run Code Online (Sandbox Code Playgroud)

如果我从测试中调用它并且测试失败,我在调用堆栈中得到两个项目:

1) PreferencesTest::testSignupTeacher
Failed asserting that 5 matches expected 3.

/vagrant/myproject/tests/integration/PreferencesTest.php:17
/vagrant/myproject/tests/integration/PreferencesTest.php:136
Run Code Online (Sandbox Code Playgroud)

第17行是assertFoo()调用内置函数assertEquals()并失败的地方; 第136行assertFoo()被称为.

如果我改变测试assertEquals()直接调用,我只得到一个:

1) PreferencesTest::testSignupTeacher
Failed asserting that 3 is true.

/vagrant/myproject/tests/integration/PreferencesTest.php:136
Run Code Online (Sandbox Code Playgroud)

手册中有一些文档,但它似乎没有涵盖这一点.

Dar*_*ook 4

我对这个问题的第一个猜测(你没有使用其中一个PHPUnit_Framework_Constraint_*对象 和self::assertThat)结果证明是完全无关的!实际的答案是 phpUnit 有助于从堆栈跟踪中过滤掉其自己代码库中的任何内容,而只将函数留在用户空间中!

执行此操作的代码可以在/path/to/PHPUnit/Util/Filter.php中找到(其中/path/to/在我的机器上是/usr/share/php),感兴趣的函数是getFilteredStacktraceisFiltered

如果您想控制此行为,请将自定义断言放入从 派生的类中PHPUnit_Framework_TestCase,然后从该类派生您的测试。在您的自定义类文件中,在某处调用addFileToFilter,如下所示:

class My_Base_TestCase extends PHPUnit_Framework_TestCase{
  public static function assertFoo($expected, $actual) {
    self::assertEquals($expected, $actual); 
  }
}

PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'DEFAULT');
Run Code Online (Sandbox Code Playgroud)

然后在另一个文件中你有:

class CustomTest extends My_Base_TestCase{

  /** */
  public function testSomething2(){
    $this->assertFoo( 8,  5+4 );
  }
}
Run Code Online (Sandbox Code Playgroud)

它的行为就像内置的assertEquals().

免责声明:这是使用未记录的行为!我将尝试找出该机制是否能够合理地适应未来。