class Connect
{
private $dbName;
public function __construct($dbName)
{
$this->dbName = $dbName;
}
public function getQuery()
{
return $this->dbName;
}
}
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');
}
}
class Member
{
private $connect;
public function __construct(ConnectFacade $connect)
{
$this->connect = $connect;
}
public function data()
{
return $this->connect->dbA->getQuery();
}
}
require 'vendor/autoload.php';
echo (new Member(new ConnectFacade))->data();
在我的情况下,我需要在一个类中连接许多数据库中的许多表,因此我需要经常声明许多具有不同连接名称的连接,因此我将其放到ConnectFacade
以节省时间,我知道它有点复杂,但这是我公司的结构,这个示例代码将在index.php上显示connect to database a
,当然实际上连接正在做很多事情,我的问题是我不知道如何嘲笑这种情况,这就是我试过的
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:\www\phpunit\class\Member.php on line 14
,我不知道如何让测试通过。
答案 0 :(得分:1)
问题是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);
}