PHPUnit测试使用pdo的受保护静态方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHPUnit测试使用pdo的受保护静态方法相关的知识,希望对你有一定的参考价值。
我对TDD很新。我正在使用phpunit 7.4x-dev。我有以下抽象类,我正在尝试开发单元测试。
use PDO;
abstract class Model {
protected static function getDB() {
static $db = null;
if ($db === null) {
$db = new PDO(ConfigDatabase::DSN, ConfigDatabase::USER, ConfigDatabase::PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return $db;
}
}
我已经创建了以下测试来解决静态保护方法的需要。如果我提供“ConfigureDatabase”类,它就可以工作。
use PHPUnitFrameworkTestCase;
class ModelTest extends TestCase {
function newMockClass(){
$stub = new class() extends Model{
function getStaticMethod($methodName){
return self::$methodName();
}
};
return $stub;
}
public function testDatabaseExists() {
$stub = $this->newMockClass();
$db = $stub->getStaticMethod('getDB');
$this->assertInstanceOf(PDO::class,$db);
}
}
由于我不希望我的测试依赖于任何实际的数据库,我如何伪造对PDO的调用。
答案
根据Dormilich的建议,我开发了一个数据库界面,以防我后来决定不想使用PDO。
interface CRUDImp {
function __construct($datbaseBridgeLikePDO);
...
}
接下来,我为构造函数编写了测试。我使用setup来确保我开始使用 PDO的新模拟。
class PDOWrapperTest extends TestCase {
private $pdoMock;
private $db;
function setup() {
$this->pdoMock = $this->createMock('PDO');
$this->db = new PDOWrapper($this->pdoMock);
}
public function testWrapperExists() {
$this->pdoMock->method('getAttribute')->willReturn(PDO::ERRMODE_EXCEPTION);
$db = new PDOWrapper($this->pdoMock);
$x = $db instanceof CRUDImp;
$this->assertTrue($x);
}
/**
* @expectedException Exception
*/
public function testNonPDOPassedToConstructor() {
$mock = $this->createMock('Exception');
$x = new PDOWrapper($mock);
}
...
}
由于PHP是松散类型的,我检查以确保传递给构造函数的类是 PDO的实例。我按如下方式实现了具体类
class PDOWrapper implements CRUDImp {
private $pdo;
private $dataOutputType = PDO::FETCH_ASSOC;
public function __construct($pdo) {
if (!($pdo instanceof PDO)) {
throw new Exception("PDOWrapper must be passed instance of PDO");
}
$attr_Errmode = $pdo->getAttribute(PDO::ATTR_ERRMODE);
if ($attr_Errmode !== PDO::ERRMODE_EXCEPTION) {
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
$this->pdo = $pdo;
}
...
}
现在我有一个独立的数据库包装器,原始模型测试目前是微不足道的,不再需要。抽象类Model修改如下:
abstract class Model {
protected $database=null;
function __construct(CRUDWrapper $database) {
$this->database = $database;
}
...
}
所以对于那些不熟悉依赖注入的人,我发现以下链接很有帮助:
http://php-di.org/doc/understanding-di.html https://codeinphp.github.io/post/dependency-injection-in-php/ https://designpatternsphp.readthedocs.io/en/latest/Structural/DependencyInjection/README.html
希望这会缩短某人的工作。
以上是关于PHPUnit测试使用pdo的受保护静态方法的主要内容,如果未能解决你的问题,请参考以下文章