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

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

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

  1. [
  2. {
  3. "ID": "1",
  4. "person_id": "1",
  5. "pc_name": "my_computer"
  6. }
  7. ]

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

  1. [
  2. {
  3. "ID": "1",
  4. "person_id": "http://localhost/api/db/person/1",
  5. "pc_name": "my_computer"
  6. }
  7. ]

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

  1. SELECT
  2. *
  3. FROM
  4. INFORMATION_SCHEMA.KEY_COLUMN_USAGE
  5. WHERE
  6. TABLE_SCHEMA = ? AND
  7. CONSTRAINT_NAME != "PRIMARY" AND
  8. REFERENCED_TABLE_NAME IS NOT NULL AND
  9. REFERENCED_COLUMN_NAME IS NOT NULL

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

0qx6xfy6

0qx6xfy61#

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

  1. class PDOMySQLForeignKeysToURLsService {
  2. protected $pdo;
  3. public function __construct(string $pdoDSN, string $username, string $password, string $tablename, string $schemaname) {
  4. $this->pdo = $this->createPdo(...);
  5. }
  6. // Encapsulate the PDO creation so that the subclass can override it.
  7. protected function createPdo(...) {
  8. return new PDO(...);
  9. }
  10. // Other methods omitted...
  11. }
  12. class TestablePDOMySQLForeignKeysToURLsService extends PDOMySQLForeignKeysToURLsService {
  13. // Override the constructor so you can pass in a mock PDO as the last parameter
  14. public function __construct(string $pdoDSN, string $username, string $password, string $tablename, string $schemaname, PDO $pdo) {
  15. // Save the injected mock PDO instance.
  16. $this->pdo = $pdo;
  17. parent::__construct(...);
  18. }
  19. // Override the creation so that you can just use the injected mock.
  20. protected function createPdo(...) {
  21. return $this->pdo;
  22. }
  23. }

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

展开查看全部

相关问题