您将如何测试使用全局变量的PHP代码?

时间:2015-03-20 12:36:59

标签: php unit-testing pdo phpunit

假设类Account(在account.php文件中)使用$ DB变量在数据库中存储数据。 $ DB变量在另一个globals.php文件中初始化。


/**** globals.php ****/

$DB = PDO (....);

/**** account.php ****/

public function create($data) {
global $DB;
....
}

现在,假设您要使用PHPUnit测试在名为create的帐户类中测试函数。你会如何初始化$ DB对象?

2 个答案:

答案 0 :(得分:1)

理想情况下,您不应该使用隐藏依赖关系的全局变量,并且可能会因全局变量的变化而导致事情发生。

你可以入侵并替换你的变量,以便你可以嘲笑它。您可以使用setUp方法存储全局$DB中的内容,然后使用teardown()方法将其恢复。这样,你不会意外地用你的模拟破坏其他测试。

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;
}

现在只是因为你能做到这一点,并不意味着你应该这样做。最好重构代码,使其不依赖于全局范围。但是,如果目前这不是一个选项,那么解决这个问题至少可以使测试在你重构之前可用。

答案 1 :(得分:0)

  

您如何初始化$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"));

        ...
    }
}

然后从测试开始,并了解代码在完全测试时的行为。

然后,您可以考虑在创建一次测试类之前初始化数据库连接,以便您可以更快地编写测试例程。

稍后您可能会自己编写一个帮助方法来实例化帐户类。

那也许是你意识到将数据库连接对象注入构造函数的时间也可能不那么糟糕。