【问题标题】:Mocking PDO with phpunit用 phpunit 模拟 PDO
【发布时间】:2015-11-01 09:30:03
【问题描述】:

我试图模拟 PDO 对象以在使用 phpunit 编写一些测试时使用,但我发现它非常复杂并且找不到太多关于它的文档。 我创建了这个 xml 结构:

<dataset>
    <table name="providers">
            <column>id</column>
            <column>name</column>
            <column>description</column>
            <row>
                    <value>1</value>
                    <value>provdier_1</value>
                    <value>phpunit first provider</value>
            </row>
    </table>
</dataset>

现在我想查询providers 表并取回数据,但我不知道该怎么做。

我从模拟PDO 对象开始,但我不明白我应该如何使用它以及如何在getConnection() 方法中使用它。 我的第一次尝试,我猜它与正确的方法相去甚远,因为我在这里很迷茫,看起来像这样:

class AdProvidersTest extends PHPUnit_Extensions_Database_TestCase
{
    public function getConnection()
    {
      $dsn = 'mydb';
      $user = '';
      $password = '';

      $pdo = $this->getMockBuilder('PDOMock')
        ->getMock();

        return $this->createDefaultDBConnection($pdo, 'adserverTesting');
    }

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

}

如何使连接与'adserverTesting.xml' 文件交互,如何使用以下行查询它:

$ds = new PHPUnit_Extensions_Database_DataSet_QueryDataSet($this->getConnection());
$ds->addTable('adserverTesting', 'SELECT * FROM providers');

【问题讨论】:

    标签: php mysql pdo mocking phpunit


    【解决方案1】:

    您是否尝试过查看documentation? 他们似乎正在使用传统的 PDO 对象,使用内存中的 sqlite 连接,方法是像您尝试做的那样用 xml 数据加载它

    <?php
    
    class AdProvidersTest extends PHPUnit_Extensions_Database_TestCase
    {
        /**
         * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
         */
        public function getConnection()
        {
            $pdo = new PDO('sqlite::memory:');
            return $this->createDefaultDBConnection($pdo, ':memory:');
        }
    }
    

    编辑:2020 年 5 月 - 单元测试用于测试代码单元,而不是测试您的数据集。最好的做法是模拟您的依赖项以返回已知数据集,而不是查询内存数据库。查询数据最适合集成测试,这是一组完全不同的测试。见https://phpunit.readthedocs.io/en/9.1/test-doubles.html?highlight=database#stubs

    【讨论】:

    • 文档已过时,新文档中没有相关文档
    • @PM7Temp 在单元测试中使用数据库通常是个坏主意。推荐的解决方案是模拟您的数据方法以在代码中返回已知数据集。请参阅示例 8.10 phpunit.readthedocs.io/en/9.1/… 周围有关数据库的亮点
    【解决方案2】:

    根据文档createXMLDataSet xml文件格式是

     It is a very simple xml format where a tag inside the root node <dataset> represents exactly one row in the database. The tags name equals the table to insert the row into and an attribute represents the column.
    

    这个xml文件代表数据(不是模式)。

    我相信您想测试您的查询和结果。所以恕我直言,最好使用测试数据库和真实连接。 http://www.liquibase.org/ 之类的迁移工具对于准备数据库和回滚数据库非常有帮助。 您也可以使用一些伪造者来生成请求/数据,例如https://packagist.org/packages/fzaninotto/faker

    【讨论】:

      【解决方案3】:

      您不必模拟 PDO。这里举例说明它是如何工作的:

      ConnectionTest.php:

      <?php
      
      class ConnectionTest extends PHPUnit_Extensions_Database_TestCase
      {
          public function getConnection()
          {
              $database = 'myguestbook';
              $user = 'root';
              $password = '';
              $pdo = new PDO('mysql:host=localhost;dbname=myguestbook', $user, $password);
              $pdo->exec('CREATE TABLE IF NOT EXISTS guestbook (id int, content text, user text, created text)');
              return $this->createDefaultDBConnection($pdo, $database);
          }
      
          public function getDataSet()
          {
              return $this->createFlatXMLDataSet(__DIR__.'/dataSets/myFlatXmlFixture.xml');
          }
      
          public function testGetRowCount()
          {
              $this->assertEquals(2, $this->getConnection()->getRowCount('guestbook'));
          }
      }
      

      myFlatXmlFixture.xml

      <?xml version="1.0" ?>
      <dataset>
          <guestbook id="1" content="Hello buddy!" user="joe" created="2010-04-24 17:15:23" />
          <guestbook id="2" content="I like it!" user="nancy" created="2010-04-26 12:14:20" />
      </dataset>
      

      结果:

      PHPUnit 4.7.6 by Sebastian Bergmann and contributors.
      
      .
      
      Time: 215 ms, Memory: 5.25Mb
      
      OK (1 test, 1 assertion)
      

      针对 db 测试的要点是不要模拟 db,但也要创建绝对相同的 PDO 连接,不是到生产数据库而是到 db 进行测试,它可以是 mysql、sqlite 等...

      【讨论】:

        猜你喜欢
        • 2011-03-09
        • 1970-01-01
        • 2011-07-19
        • 2011-07-17
        • 2020-10-25
        • 1970-01-01
        • 1970-01-01
        • 2020-05-08
        • 2013-07-29
        相关资源
        最近更新 更多