【问题标题】:PHPUnit testing a method that depends on another methodPHPUnit 测试一个依赖于另一个方法的方法
【发布时间】:2020-01-25 19:35:15
【问题描述】:

这是我的数据库类,我想测试返回正确值的 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());
    }
}

现在我的问题是:我认为这不是一个好方法,而 statement 是私有财产。在第二次测试中,我只能测试 rowCount 方法,但我使用了私有财产,我认为它会使将来的维护变得如此困难。 哪一个是正确的?我应该以其他方式对其进行测试吗?

【问题讨论】:

    标签: php unit-testing phpunit


    【解决方案1】:

    您可以使用@depends,它允许您显式声明测试之间的依赖关系:

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

    其中yourQueryTest 是对\MyProject\Database\Database#query 的测试。

    【讨论】:

      猜你喜欢
      • 2016-12-30
      • 1970-01-01
      • 2023-04-10
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多