4

PHPUnit/DBUnitを使用してZendFrameworkDbTableモデルをテストしようとしています。タイムスタンプのあるテーブルにつまずきました。

assertDataSetsEqualを使用して、挿入の実際の結果を期待される結果と比較しようとしています。もちろん、タイムスタンプ付きのテーブルにレコードを挿入すると、タイムスタンプフィールドに現在の日付/時刻が入力されます。期待されるデータを表すデータセットは静的であるため、タイムスタンプは一致しません。

この状況にどのように対処できますか?アサーションにタイムスタンプ列を無視させることはできますか?

4

3 に答える 3

2

このブログ投稿のおかげで、これに対するはるかに優れた解決策を見つけました。

2つのデータセットが等しいことを簡単に表明できる関数を作成しました。

protected function assertDataSetEquals(
        $ExpectedXMLFileName,
        array $options = array()) {

    $model  = (isset($options['model'])) ?
        $options['model'] :
        $this->_object;
    $excludeColumns = (isset($options['excludeColumns'])) ?
        $options['excludeColumns'] :
        null;

    $ds = new Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet();
    $ds->addTable($model);

    $dsFiltered = (isset($excludeColumns)) ?
        $this->filterColumns($model, $ds, $excludeColumns) :
        $ds;

    $this->assertDataSetsEqual(
        $this->createFlatXmlDataSet(
            APPLICATION_PATH 
            . '/../tests/fixtures/models/'
                . $ExpectedXMLFileName . '.xml'
        ),
        $dsFiltered
    );
}

そして、フィルタリングされたデータセットを返すプライベート関数。

private function filterColumns(
        $model,
        $dataSet,
        $excludeColumns) {

    $dsFiltered = 
        new PHPUnit_Extensions_Database_DataSet_DataSetFilter($dataSet);
    $dsFiltered->setExcludeColumnsForTable(
            $model->getName(),
            $excludeColumns
        );

    return $dsFiltered;
}

次に、列を除外して2つのデータセットを比較するために、これを実行します。

    $this->assertDataSetEquals(
            'TableWithTimestampIWantToIgnoreUpdate',
            array('excludeColumns'=>array('timestamp','id'))
        );

これにより、タイムスタンプ列を持つテーブルに対応するモデルをテストするためのはるかに簡単でクリーンな方法が可能になります。

于 2012-07-24T17:37:32.893 に答える
0

これが可能だと思わせるようなものは何も見つかりませんでした。

私が最終的に解決した方法は、更新後にテーブルをクエリし、結果を配列に保存してから、assertEqualsを使用して適切なフィールドが更新されたことを確認することでした。

于 2012-07-20T19:29:26.963 に答える
0

bconradのおかげで、この関数をテストクラスに追加しました。

/**
 * @param Zend_Test_PHPUnit_Db_DataSet_QueryDataSet $dataSet
 * @param array $excludeTheseColumnsOfTheseTables Array where the keys are table names and the values are arrays of column names to exclude.
 * @return PHPUnit_Extensions_Database_DataSet_DataSetFilter
 * @see http://stackoverflow.com/a/11636295/470749
 */
protected function filterColumns($dataSet, $excludeTheseColumnsOfTheseTables)
{
    $filteredDataset = new \PHPUnit_Extensions_Database_DataSet_DataSetFilter($dataSet);
    foreach ($excludeTheseColumnsOfTheseTables as $tableName => $excludedColumns) {
        $filteredDataset->setExcludeColumnsForTable($tableName, $excludedColumns);
    }
    return $filteredDataset;
}

次に、データセットのフィルタリングは次のように簡単です。

$queryDataSet = new \Zend_Test_PHPUnit_Db_DataSet_QueryDataSet($this->getConnection());
$queryDataSet->addTable('posts', 'SELECT * FROM posts');
$queryDataSet->addTable('users', 'SELECT * FROM users');
$excludeTheseColumnsOfTheseTables = array(
    'users' => array('created', 'modified'),
    'posts' => array('modified'));
$filteredDataset = $this->filterColumns($queryDataSet, $excludeTheseColumnsOfTheseTables);
$this->assertDataSetsEqual($this->getAssertionXmlDataSet('asrt.xml'), $filteredDataset);
于 2014-05-22T23:11:21.857 に答える