<?php
class Game
{
public $db;
public function __construct()
{
$this->db = new DB;
}
public function result()
{
return $this->db->data();
}
}
<?php
class DB
{
public function data()
{
return false;
}
}
<?php
use Mockery as m;
class GameTest extends PHPUnit_Framework_TestCase
{
public function testResult()
{
$game = m::mock(new Game);
$game->shouldReceive('data')
->once()
->andReturn(true);
$expected = $game->result();
$this->assertTrue($expected);
}
public function tearDown()
{
m::close();
}
}
This is my solution but totally not work, I guess if I want to get setting from __construct
I need to mock a new class, I got message Failed asserting that false is true.
which mean the mock thing is not work, how to deal with it?
You can't do it like that, best solution would be to use dependency injection for $db. That way you can mock only DB like this...
$dbMock = m::mock('DB');
$dbMock->shouldReceive('data')
->once()
->andReturn(true);
Or you can keep you constructor like this (without DI), but you will have to mock that constructor also.
You can use Mockery by creating an "instance mock" for the DB class like this:
$dbMock = Mockery::mock('overload:MyNamespace\DB');
This will "intercept" when a new instance of the DB class is created and the $dbMock will be used instead. When the $dbMock
is created you just need to add an expectation declaration for the given method:
$dbMock->shouldReceive('data')
->once()
->andReturn(true);