PHPUnit тестирует метод, который зависит от другого метода - PullRequest
0 голосов
/ 25 января 2020

Это мой класс базы данных, и я хочу проверить rowCount метод, возвращающий правильное значение:

namespace MyProject\Database;

class Database {

    // database connection
    private $conn = NULL;

    // holds query statement object
    private $statement = NULL;

    public function __construct(\PDO $conn) {

        $this->conn = $conn;
    }

    public function query(string $query, array $parameters=[]) : bool {

        $this->statement = $this->conn->prepare($query);
        return $this->statement->execute($parameters);
    }

    public function rowCount() : int {

        return $this->statement->rowCount();
    }
}

Сначала я написал этот модульный тест для проверки rowCount метод, но, как вы можете видеть, я также использовал метод query для выполнения запроса:

class DatabaseTest extends \PHPUnit\Framework\TestCase {

    /** @test */
    public function rowCountReturnsCorrectNumber() {

        $pdo = new \PDO('sqlite::memory:');

        $db = new \MyProject\Database\Database($pdo);

        // we are not testing query method here but we use it to run the query
        $db->query("CREATE TABLE test (id INT UNSIGNED PRIMARY KEY)");
        $db->query("INSERT INTO test (id) VALUES (1),(2)");

        $this->assertEquals(2,$db->rowCount());
    }
}

Я думал, query метод может иметь ошибки в будущем, так почему я должен зависеть от этого. Я написал это, чтобы избежать этого:

class DatabaseTest extends \PHPUnit\Framework\TestCase {

    /** @test */
    public function rowCountReturnsCorrectNumber() {

        $pdo = new \PDO('sqlite::memory:');

        $db = new \MyProject\Database\Database($pdo);

        $s = $pdo->prepare("CREATE TABLE test (id INT UNSIGNED PRIMARY KEY)");
        $s->execute();
        $s2 = $pdo->prepare("INSERT INTO test (id) VALUES (1),(2)");
        $s2->execute();

        // here I set statement (private property)
        $reflection = new \ReflectionClass($db);
        $property = $reflection->getProperty('statement');
        $property->setAccessible(true);
        $property->setValue($db, $s2);

        $this->assertEquals(2,$db->rowCount());
    }
}

Теперь мой вопрос таков: я думаю, что это не очень хороший подход, в то время как заявление является частной собственностью. Во 2-м тесте я могу протестировать только метод rowCount и ничего больше, кроме того, что я использовал частную собственность, и я думаю, что в будущем это может так усложнить обслуживание. Какой из них правильный? Должен ли я проверить это по-другому?

1 Ответ

1 голос
/ 25 января 2020

Вы можете использовать @depends, который позволяет вам явно объявить зависимости между вашими тестами:

class DatabaseTest extends \PHPUnit\Framework\TestCase
{
  /**
   * @test
   */
  public function yourQueryTest()
  {
    // ...
  }


  /**
   * @test
   * @depends yourQueryTest
   */
  public function rowCountReturnsCorrectNumber()
  {
    // ...
  }
}

, где yourQueryTest - это тест для \MyProject\Database\Database#query.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...