假设类Account(在Account.php文件中)使用$DB变量在数据库中存储数据。$DB变量在另一个globals.php
文件中初始化。
/**** globals.php ****/
$DB = PDO (....);
/**** account.php ****/
public function create($data) {
global $DB;
....
}
现在,假设您想使用PHPUnit测试来测试account类create中的一个函数。您将如何初始化$DB对象?
理想情况下,您不应该使用隐藏依赖关系的全局变量,因为全局变量的更改可能会导致事情发生。
你可以破解并替换你的变量,这样你就可以模拟它。你可以使用setUp
方法来存储全局$DB
中的内容,然后在teardown()
方法中恢复它。这样,您就不会意外地用mock破坏其他测试。
public function setUp() {
global $DB;
$this->oldDB = $DB;
}
public function testCreate() {
$mockDB = $this->getMock('PDO') ... //More steps to complete mock object
global $DB;
$DB = $mockDB;
//Rest of Test here
}
public function teardown() {
global $DB;
$DB = $this->oldDB;
}
现在,仅仅因为你可以这样做,并不意味着你应该这样做。最好重构代码,使其不依赖于全局范围。但是,如果目前还不能这样做,那么这里有一个解决方案,它至少会使测试在重构之前可用。
您将如何初始化
$DB
对象?
只需像往常一样初始化:
class TestCase extends PHPUnit_Framework_TestCase
{
function testDatabaseConnection()
{
require 'path/to/globals.php'; // take "global" variable in local scope
$GLOBALS['DB'] = $DB; // make it globally available
$account = new account();
$this->assertInstanceOf('account', $account);
$this->assertTrue($account->create("data"));
...
}
}
然后从测试开始,当您对代码进行彻底测试时,可以感受到代码的行为。
然后可以考虑在创建测试类之前初始化数据库连接,这样可以更快地编写测试例程。
- 第4章。固定装置
稍后,您可能会为自己编写一个助手方法来实例化帐户类。
这时,您可能也会意识到,将数据库连接对象注入构造函数可能不会那么糟糕。