mysql—单元测试一个php类,该类接受字符串参数来创建pdo对象

cczfrluj  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(380)

我有一节课( PDOMySQLForeignKeysToURLsService )这正是它在tin上所说的,它采用json编码的数据库实体,将其与配置文件进行比较,并将任何外键字段转换为链接到其他restful资源的url。即

[
  {
    "ID": "1",
    "person_id": "1",
    "pc_name": "my_computer"
  }
]

假设 person_id 是数据库中的外键,会变成

[
  {
    "ID": "1",
    "person_id": "http://localhost/api/db/person/1",
    "pc_name": "my_computer"
  }
]

因为此服务本身是从配置文件初始化的,所以它只能接受其构造函数中的文本, public function __construct(string $pdoDSN, string $username, string $password, string $tablename, string $schemaname) 一切似乎都运行得很好,但现在我想为这个类编写一些单元测试,其中一部分要求 PDO 对象被示例化 INFORMATION_SCHEMA 如下表所示

SELECT 
    *
  FROM
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE
  WHERE
    TABLE_SCHEMA = ? AND
    CONSTRAINT_NAME != "PRIMARY" AND
    REFERENCED_TABLE_NAME IS NOT NULL AND
    REFERENCED_COLUMN_NAME IS NOT NULL

发生这种情况的方法是在接口的实现中 Resolvable ,定义 function resolveRequest(ServiceRequest $request, ServiceResponse $response) 除了在测试中设置一个模式/一些表之外,我基本上不知道如何测试所有这些?我从我的同行那里听说过,这是一种不好的做法,不构成单元测试,而是集成测试——所以我的问题是,我该如何进行单元测试这种方法,单元测试在这里合适吗?根据定义,这个类非常依赖于mysql(和pdo)。我是否应该围绕pdo编写某种适配器,并使用di框架来注入它,并与之接口,而不是直接与pdo接口?我完全不知道该怎么做,tbh,也不明白如何模拟只在方法范围内使用的依赖关系

0qx6xfy6

0qx6xfy61#

即使不能注入pdo示例,仍然有一些方法可以对其进行单元测试——这只需要一点创造性。可能最简单的单元测试方法是创建一个允许注入的可测试子类。具体细节将取决于类的实现方式,但一个简单的示例可能如下所示:

class PDOMySQLForeignKeysToURLsService {
    protected $pdo;

    public function __construct(string $pdoDSN, string $username, string $password, string $tablename, string $schemaname) {
        $this->pdo = $this->createPdo(...);
    }

    // Encapsulate the PDO creation so that the subclass can override it.
    protected function createPdo(...) {
        return new PDO(...);
    }

    // Other methods omitted...
}

class TestablePDOMySQLForeignKeysToURLsService extends PDOMySQLForeignKeysToURLsService {
    // Override the constructor so you can pass in a mock PDO as the last parameter
    public function __construct(string $pdoDSN, string $username, string $password, string $tablename, string $schemaname, PDO $pdo) {
        // Save the injected mock PDO instance.
        $this->pdo = $pdo;
        parent::__construct(...);
    }

    // Override the creation so that you can just use the injected mock.
    protected function createPdo(...) {
        return $this->pdo;
    }
}

这个 TestablePDOMySQLForeignKeysToURLsService 类将位于测试的旁边,您将在测试用例中使用它,而不是在生产类中使用它。其思想是“可测试”类是生产类的最小扩展—只足以让您注入测试双倍。这使您可以测试生产类的逻辑,并在测试中模拟数据库调用,而无需更改生产类的接口。这有点作弊,但它能完成任务。

相关问题