如何模拟其他班级中的班级



Connect.php

class Connect
{
    private $dbName;
    public function __construct($dbName)
    {
        $this->dbName = $dbName;
    }
    public function getQuery()
    {
        return $this->dbName;
    }
}

连接立面.php

class ConnectFacade
{
    public $dbA;
    public $dbB;
    public $dbC;
    public $dbD;
    public function __construct()
    {
        $this->dbA = new Connect('connect to database a');
        $this->dbB = new Connect('connect to database b');
        $this->dbC = new Connect('connect to database c');
        $this->dbD = new Connect('connect to database d');
    }
}

成员.php

class Member
{
    private $connect;
    public function __construct(ConnectFacade $connect)
    {
        $this->connect = $connect;
    }
    public function data()
    {
        return $this->connect->dbA->getQuery();
    }
}

索引.php

require 'vendor/autoload.php';
echo (new Member(new ConnectFacade))->data();

就我而言,我有许多来自许多数据库的表需要连接在一个类中,因此我需要经常声明许多具有不同连接名称的连接,所以我把它放在ConnectFacade以节省时间,我知道这有点复杂,但这就是我公司的结构,此示例代码将显示索引connect to database a.php, 当然,实际上连接正在做很多事情,我的问题是我不知道在这种情况下有多模拟,这就是我尝试过的

use Mockery as m;
class MemberTest extends PHPUnit_Framework_TestCase
{
    public function testData()
    {
        $connect = m::mock('ConnectFacade');
        $connect->shouldReceive('dbA->getQuery')
            ->once()
            ->andReturn(true);
        $actual = (new Member($connect))->data();
        $this->assertTrue($actual);
    }
    public function tearDown()
    {
        m::close();
    }
}

而且我得Call to a member function getQuery() on a non-object in D:wwwphpunitclassMember.php on line 14,我不知道如何使测试通过。

问题是dbA不是 ConnectFacade 上的方法,而是一个变量。因此$connect->shouldReceive('dbA->getQuery')不起作用。

相反,您需要将dbA变量设置为模拟,然后将期望更改为仅接收getQuery

public function testData()
{
    $connect = m::mock('ConnectFacade');
    $connect->dbA = $connect;
    $connect->shouldReceive('getQuery')
        ->once()
        ->andReturn(true);
    $actual = (new Member($connect))->data();
    $this->assertTrue($actual);
}

另一种选择是在 ConnectFacade 中模拟 Connect 类的创建,而不是模拟整个 ConnectFacade:

public function testData()
{
    $connect = m::mock('overload:Connect');
    $connect->shouldReceive('getQuery')
        ->once()
        ->andReturn(true);
    $connectFacade = new ConnectFacade;
    $actual = (new Member($connectFacade))->data();
    $this->assertTrue($actual);
}

最新更新