【问题标题】:PHPUnit Testing a select in a method with datasetPHPUnit 使用数据集测试方法中的选择
【发布时间】:2012-11-27 21:03:47
【问题描述】:

我尝试测试一种进行 SELECT 查询并返回找到的行的方法。给定数据集,我想检查此方法是否不返回其他内容。我发现了很多关于创建数据集的文档,但没有关于在我的案例中使用它...感谢您的帮助。

测试方法是:

class A
{
  public static function myMethod()
  {
    $result = mysql_query("SELECT * FROM user");
    [...]
    return $rows;
  }
}

测试类是:

class ATest extends PHPUnit_Extensions_Database_TestCase
{
  protected $pdo;

  public function __construct()
  {
    $this->pdo = new PDO('mysql:host=localhost;dbname=db_name',
                         'login', 'password');
  }

  public function getConnection()
  {
    return $this->createDefaultDBConnection($this->pdo, 'db_name');
  }

  public function getDataSet()
  {
    return $this->createFlatXMLDataSet('mydataset.xml');
  }

  public function testMyMethod()
  {
    $actual = A::myMethod();
    $this->assertEquals(array([...]), $actual);
    // For this test, I get a mySQL error "No database selected"
    // in A::myMethod()!
  }
}

这里是mydataset.xml的内容:

<?xml version="1.0" ?>
<dataset>
  <user iduser="1" name="John" />
  <user iduser="2" name="James" />
</dataset>

【问题讨论】:

    标签: php mysql database unit-testing phpunit


    【解决方案1】:

    就像在您的真实应用程序中一样,您需要先连接到数据库,然后才能调用它。 mysql_query() 函数依赖于先前对 mysql_connect() 的调用。如果您只单独调用一个类方法,那么您将不会调用 connect 函数,因此您将没有连接,因此您的查询命令将不知道它需要查询哪个数据库。

    在测试类中使用的 PDO 连接明确地与被测试的方法分开并且不被测试的方法使用(即使这些方法也使用 PDO);您需要为查询创建一个连接。

    这里的解决方案是在测试开始时调用您的数据库连接方法。这可能在单元测试方法中,或者在测试类的 setUp() 方法中,或者在 PHPUnit 在运行任何测试之前调用的引导文件中。您使用哪一种取决于您需要运行多少数据库测试以及跨越多少测试类。

    稍微偏离主题,但仍然相关:我注意到您的代码使用旧的mysql_xxx() 函数(即mysql_query())。建议避免使用这些函数,因为它们已经过时且不安全,并且正在被 PHP 开发团队弃用。因此,如果您继续使用它们,您将发现自己将来无法升级您的 PHP 版本。

    改用mysqli_xxx()(或PDO,根据您的测试类)。

    回到主题,实际上这样做也将引导您解决您遇到的问题,因为mysqli 和 PDO 在调用它们的函数/方法时都要求连接对象可用,所以你'必须有一个有效的连接对象才能有有效的语法来调用查询。因此,切换到 mysqli 或 PDO 将迫使您以解决问题的方式编写代码。

    【讨论】:

    • 感谢您的回答 SDC。我在 setUp 中调用了我的连接脚本,但现在没有读取数据集。只有我以前在我的数据库中拥有的东西。我知道 PHPUnit 应该截断我的表,然后在开始单元测试之前插入数据集,但它只截断了我的表。是不是说明代码中的createFlatXmlDataSet()不正确?
    【解决方案2】:

    在我的情况下,我使用 pdo 连接到数据库,如下所示:

    static private $pdo=null;
    private $conn=null;
        public function getConnection()
            {
                if($this->conn===null)
                {
                    if(self::$pdo===null)
                    {
                        self::$pdo = new PDO("mysql:host=yourhost;dbname=yourdbname_",
                    "yourusername", "yourpassword");
                    }
                    $this->conn= $this->createDefaultDBConnection(self::$pdo, 'yourdbname_');
                    return $this->conn;
                }
            }, 
    

    那么对于测试,下面的这个块获取testdb中的所有值并将其与xml文件进行比较。

     public function testGetAll()
                {
                    $resultingTable = $this->db
                    ->createQueryTable("yourtable",
                    "SELECT * FROM yourtable");
                     $expectedTable = $this->getDataSet()
                    ->getTable("yourtable");
                $this->assertTablesEqual($expectedTable,
                    $resultingTable);   
                }
    

    这对我来说很好,应该允许您从 testdb 中获取所有值并断言它们与 xml 值相同。

    【讨论】:

      猜你喜欢
      • 2018-04-27
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2018-05-28
      • 2012-09-18
      相关资源
      最近更新 更多