【问题标题】:Phpunit testing with database使用数据库进行 Phpunit 测试
【发布时间】:2011-06-02 21:21:07
【问题描述】:

我正在尝试使用 PHPunit 进行单元测试。

我在这里找到了一个很好的教程http://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282

但是我缺少一些东西,还不知道该怎么做。

我有一个用户模块,它维护有关用户的所有信息。并且有一个函数 save 可以将用户保存在数据库中。所以我有一个testFunction

public function testCanCreateUser()
{
    $userData = array(
        'userName'  =>  'User1',
        'firstName' =>  'Joey',
        'lastName'  =>  'Hendricks',
        'email'     =>  'Joey@hendricks.com',
        'password'  =>  'f$tfe8F'
    
    ); 
    $user = new Model_User($userData);
    $user->save();
     
}

当我第一次运行我的测试时,这将起作用。由于数据库是空的。但是当我第二次运行我的测试时它不会工作,因为我的系统不允许同一个用户在数据库中两次。所以为了做到这一点,我必须在每次运行测试之前重新创建我的测试数据库。最好的方法是什么?

或者这个问题要换个方式解决?

【问题讨论】:

    标签: php unit-testing zend-framework phpunit


    【解决方案1】:

    如果你想测试你的业务逻辑:模拟掉 Database 类并返回假数据

    如果你想测试触发 SQL 语句的类(恕我直言,你也可以测试一下,因为我有点想知道我的代码是否可以在后端的真实数据库中正常工作)它得到有点复杂,但有办法做到这一点:

    • 在运行测试之前使用 setUp() 和 tearDown() 获得一致的数据状态是(恕我直言)编写数据库驱动单元测试的好方法。但是,手动编写大量自定义 sql 会很烦人。

    • 为了让您的生活更轻松,您可以查看 DbUnit extension 并查看它是否适用于您的应用程序。

    • 如果您真的想深入了解单元测试数据库交互,最好阅读(恕我直言)Sebastian Bergmanns phpqa book 中关于 db-unittesting 的章节。

      李>
    • 您的应用程序是否允许自定义数据库名称和所有表的自动设置,也可以使用大量测试数据设置一次数据库并在所有测试中使用该数据。你可以小心一点,尽管一个测试不依赖于另一个测试写入的数据。

    【讨论】:

    • 只是想知道您是如何知道 Sebastion Bergmanns 书中的一篇好文章尚未出版的。但这仍然是一件复杂的事情。
    【解决方案2】:

    使用其他空的和/或在setUp()tearDown() 方法中清除的数据库副本运行测试,但注意不要执行github did 的操作。

    如果您使用的是良好的数据库(即不是带有 MyISAM 表的 MySQL),您可以将测试包装在事务中并在测试后回滚:

     function setUp() { $this->db->exec("BEGIN"); }
     function tearDown() { $this->db->exec("ROLLBACK"); }
    

    缺点是您无法测试使用事务的代码(除非您将其抽象化并使用保存点进行模拟,但这是不确定的)。

    理想情况下,您应该使用依赖注入并在假数据库类上运行测试:

    $fakedb = new DatabaseThatDoesntReallySaveThings();
    $user = new Model_User($fakedb, $userData);
    $user->save();
    $this->assertTrue($fakedb->wasAskedToSaveUser());
    

    【讨论】:

    • (new PDO())->beginTransaction() 也应该可以工作,即使是 Mariadb/mysql 数据库。
    【解决方案3】:

    我认为你可以使用tearDown() 方法来清理你保存的数据。

    protected $_user;
    
    public function testCanCreateUser()
    {
        ...
    
        $this->_user = new Model_User($userData);
        $this->_user->save();
    }
    
    public function tearDown()
    {
        $this->_user->delete();
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-02
      • 2015-01-27
      • 2011-05-14
      • 2012-07-28
      • 2011-10-10
      • 2011-05-08
      • 2011-04-11
      • 2016-06-04
      • 2019-04-18
      相关资源
      最近更新 更多