使用数据库进行Phpunit测试

时间:2011-01-03 14:40:47

标签: php unit-testing zend-framework phpunit

我正在尝试使用PHPunit关注单元测试。

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

但是我想念并且还不知道该怎么做。

我有一个用户模块,它维护有关用户的所有信息。还有一个功能保存功能可以将用户保存在数据库中。所以我有一个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();

}

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

TNX。

3 个答案:

答案 0 :(得分:22)

如果您想测试您的业务逻辑:模拟数据库类并返回虚假数据

如果你想测试触发sql语句的类(并且你可以测试一下,因为我有点想知道我的代码是否在后端使用真正的数据库工作正常)有点复杂,但有办法做到这一点:

  • 在运行测试之前使用setUp()和tearDown()为您获取数据的一致状态是(imho)编写数据库驱动的单元测试的好方法。尽管手动编写大量自定义sql会很烦人。

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

  • 如果确实希望深入了解Unittesting数据库交互,那么该主题的最佳读物是(imho)Sebastian Bergmanns phpqa book中有关db-unittesting的章节。

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

答案 1 :(得分:9)

使用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());

答案 2 :(得分:2)

我认为您可以使用tearDown()方法清除已保存的数据。

protected $_user;

public function testCanCreateUser()
{
    ...

    $this->_user = new Model_User($userData);
    $this->_user->save();
}

public function tearDown()
{
    $this->_user->delete();
}