如何使用PHPUnit来模拟和测试实例化对象的函数?

时间:2017-09-29 04:39:47

标签: php phpunit

我正在尝试编写一个函数,其目的是测试数据库连接。它的作用是实例化Database对象,尝试连接数据库并返回结果。

伪代码看起来像这样

<?php

function testDatabaseLogin() {
    // Get the database connection information from a file
    // ...

    // Database is a class which stores the connection information passed,
    // When its connect() method is invoked, it tries to connect. nothing fancy
    $conn = new Database($host, $port, $username, $password);
    return $conn->connect(); // TRUE on success, FALSE otherwise
}

?>

此代码段是我的情况的简化版本,但它应该足以说明我的问题。

我想知道如何使用PHPUnit来模拟此示例中的Database类。我想要的是我可以

  1. 断言从此函数实例化Database时的参数是正确的
  2. 保留Database以控制connect()以返回TRUEFALSE,这样我就不需要真正尝试连接到真实数据库< / LI>

    我已经四处寻找,但我发现似乎PHPUnit Mock对象不能以这种方式工作。任何帮助都很感激。在底线,如果有助于使测试更容易,则可以更改功能实现。

    谢谢。

1 个答案:

答案 0 :(得分:0)

我曾经使用过一种技巧

<?php   
class MyClass
{
   public function databaseLogin() {
        $conn = $this->createDatabase();
           return $conn->connect(); // TRUE on success, FALSE otherwise
        }

   protected function createDatabase() {
        new Database($host, $port, $username, $password);
   }
} 

然后,创建一个&#34;正在测试的班级&#34;这扩展了你的课程:

class MyClassUnderTest extends MyClass
{
   public function __construct($databaseMock)
   {
       $this->databaseMock = $databaseMock;
       parent::__construct();
   }
}

然后,在测试中:

class MySuperTest
{
    public function testSomethingWitDatabase()
    {
        $databaseMock = $this->getMockBuilder(DataBase::class)
            ->disableOriginalConstructor()
            ->getMock();

        $classUnderTest = new MyClassUnderTest($databaseMock);
        $this->assertTrue($classunderTest->databaseLogin());
    }
}

因此,您将数据库对象实例化为一个被刚刚为测试而创建的类所覆盖的方法。