PHPUnit-断言查询从数据库返回良好的数据 [英] PHPUnit - Asserting that a query returns the good data from a database

查看:8
本文介绍了PHPUnit-断言查询从数据库返回良好的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试一个Factory,它可以简单地检索新闻系统的所有"帖子"。我将把这个示例简化为尽可能简单的内容:

$newsFactory->getAllNews();

表格如下:

+---------+---------------------+-------------+
| news_id | news_publishedDate  | news_active |
+---------+---------------------+-------------+
|       1 | 2010-03-22 13:20:22 |           1 |
|       2 | 2010-03-23 13:20:22 |           1 |
|      14 | 2010-03-23 13:20:22 |           0 |
|      15 | 2010-03-23 13:20:22 |           1 |
+---------+---------------------+-------------+

我想测试该行为;目前,我们只关注第一个:

  • 确保查询只返回NEWS_ACTIVE=1
  • 确保查询将返回按News_PublishedDate排序的元素,从最新到旧。

所以我创建了一个dbData.xml我认为是好的测试数据的数据集:

<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
  <table name="news">
    <column>news_id</column>
    <column>news_publishedDate</column>
    <column>news_active</column>
    <row>
        <value>1</value>
        <value>2010-03-20 08:55:05</value>
        <value>1</value>
    </row>
    <row>
        <value>2</value>
        <value>2010-03-20 08:55:05</value>
        <value>0</value>
    </row>
    <row>
        <value>3</value>
        <value>2011-03-20 08:55:05</value>
        <value>1</value>
    </row>
  </table>
</dataset>

好的,让我们只检查第一个测试(不从XML数据集中返回news_id#2)

我必须扩展PHPUnit_Extensions_Database_TestCase类才能创建NewsFactoryTest类:

<?php
require_once 'PHPUnit/Extensions/Database/TestCase.php';

class NewsFactoryTest extends PHPUnit_Extensions_Database_TestCase
{
    protected $db;


    protected function getConnection()
    {
        $this->db = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
        return $this->createDefaultDBConnection($this->db, 'testdb');
    }

    protected function getDataSet()
    {
        return $this->createXMLDataSet(dir(__FILE__) . DIRECTORY_SEPARATOR . 'dbData.xml');
    }

    public function testGetNewsById()
    {
        $newsFactory = new NewsFactory($this->db);
        $news = $newsFactory->getNewsById();
        // ???
        $this->assertEquals(2, count($news), "Should return only 2 results");
    }
}

我的主要问题是如何设置该测试?

具体来说,我试着理解:

  • 我应该创建一个testdb数据库,还是完全是模拟/虚拟的?
    • 我看过很多使用sqlite::memory:的例子,用SQLite测试基于MySQL的查询是个好主意吗?我可以改用mysql::memory:吗?
    • 如果是真正的数据库,如何在每次测试运行之前还原数据库中dbData.xml的所有数据?
  • 我应该在哪里调用getConnection()getDataSet()

感谢阅读和分享您的知识!

推荐答案

我在我们的项目中设置了数据库测试,以下是对我们有用的一些答案和经验:

我应该创建一个testdb数据库,还是全部是模拟的/虚拟的?

我在开始时也问了同样的问题,我们都知道这确实是一个真正的数据库在运行。

我看过很多使用SQLite::Memory:的例子,用SQLite测试基于MySQL的查询是个好主意吗?我可以改用MySQL::Memory:吗?

我尝试使用SQLite来提高性能,但发现SQL会有很大的不同,不能在现有代码中随处使用。我能够对大多数表使用MySQL内存引擎(对于某些表,如BLOB列则不可能)。

如果是真正的数据库,如何在每次测试运行之前还原数据库中的所有数据?

我编写了一个脚本,从远程测试服务器调用模式及其所有表的mysqlump,将它们插入本地服务器,并将所有可能的表引擎转换为内存。这确实需要时间,但由于架构不会在不同的测试之间更改,因此它只在最顶层的TestSuite上运行一次,或者根据开发人员在其本地系统上的需要单独运行一次。

数据集在每次测试开始时加载,由于表已经存在并且在内存中,因此测试之间的插入和截断速度很快。

我应该在哪里调用getConnection()和getDataSet()?

我们已经有一个扩展了TestCase的帮助器类,所以我不能使用PHPUnit_Extensions_Database_TestCase。我将设置函数添加到该助手类中,并且从未调用或必须实现getDataSet()。我确实使用了getConnection()从Assert函数中修改的数据创建数据集。

/**
 * @param PHPUnit_Extensions_Database_DataSet_IDataSet $expected_data_fixture
 * @param string|array $tables
 */
protected function assertDataFixturesEqual($expected_data_fixture, $tables){
    if(!is_array($tables)){
        $tables = array($tables);
    }
    PHPUnit_Extensions_Database_TestCase::assertDataSetsEqual($expected_data_fixture, $this->DbTester->getConnection()->createDataSet($tables));
}

编辑: 我发现我用作PHPUnit文档的一些资源的书签有点缺失:

http://www.ds-o.com/archives/63-PHPUnit-Database-Extension-DBUnit-Port.html

http://www.ds-o.com/archives/64-Adding-Database-Tests-to-Existing-PHPUnit-Test-Cases.html

这篇关于PHPUnit-断言查询从数据库返回良好的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆