如何使用PHPUnit插入特定于测试用例的数据库行

mr.*_*. w 6 php phpunit

当使用PHPUnit测试依赖于数据库的类时,getDataSet()方法提供数据作为整个测试套件的测试夹具.这很好,但是如何为特定测试提供数据?特别是在使用最小化数据集时,每个测试需要在所有测试使用的公共数据之上使用不同的数据库数据,这并不罕见.我知道PDO对象是可用的,在我们的例子中,应用程序的本机数据库对象也可用(意思是,我们可以在应用程序中运行原始查询或使用其他功能),但是有一种方法可以插入数据这是由PHPUnit的DataSet容器驱动的,因此所有测试数据都以相同的方式处理,以提高清晰度并简化维护.

有没有办法实现这个目标?

zer*_*kms 8

你可以遵循这样的诡计:

protected function getDataSet()
{
    if (in_array($this->getName(), array('testA', 'testB', '...'))) {
        return $this->createXMLDataSet(__DIR__ . '/_fixtures/fistureA.xml');
    }

    return $this->createXMLDataSet(__DIR__ . '/_fixtures/fixtureB.xml');
}
Run Code Online (Sandbox Code Playgroud)

小注意:$this->getName()返回当前的测试方法名称

另一种方法是在测试开始时重新运行设置操作:

public function testA()
{
    $this->getDatabaseTester()->setDataSet($this->createFlatXMLDataSet(__DIR__ . '/_fixtures/fixtureForTestA.xml'));
    $this->getDatabaseTester()->onSetUp();

    /* your test code */
}
Run Code Online (Sandbox Code Playgroud)


fba*_*ien 5

这是一个迟到的答案,但它对某些人来说仍然有用我猜...

您可以通过调用可以获得的execute方法来实现此目的.你基本上会使用或.IDatabaseOperationPHPUnit_Extensions_Database_Operation_FactoryCLEAN_INSERTINSERT

作为zerkms的第二种方法,您可以在每次需要特定数据的测试开始时调用它.例如:

public function testA() {
  PHPUnit_Extensions_Database_Operation_Factory::INSERT()
    ->execute($this->getConnection(), $this->createXMLDataSet(__DIR__.'/fixtureA.xml'));

  // Test code
}
Run Code Online (Sandbox Code Playgroud)

但是,此解决方案的优点是整个测试用例的数据集保持不变,因此:

  • 测试方法保持彼此独立(而在zerkms方法中,如果您不/忘记在另一个测试方法中指定数据集,它将重用先前(随机?)方法中的数据集,该方法更改了数据集,即非常丑陋,非常容易出错恕我直言.在这里,任何其他没有这种调用的测试都会像往常一样使用测试用例数据集.
  • 您可以在公共(测试用例)数据集之上构建测试数据集.如果使用INSERT操作(不是CLEAN_INSERT),它将在公共数据集的所有行之后插入特定于测试的行.您还可以使用该DELETE操作从该公共数据集中删除一些不需要的行.
  • BTW,onSetUp()即使测试用例的设置操作已经改变,也不会调用.