The Manh Nguyen
The Manh Nguyen

Reputation: 465

Mockery does not mock propeties of class

i have test:

class ContacsBLOTest extends TestCase
{    
    public function testsearch()
    {
        $Ctrl= new ContactsBLO;
        $data=['id'=>1,'name'=>'The Manh','phone'=>'123456566','address'=>'180 cao lo','note'=>''];
        $data=[(object)$data];

        $mock_data=\Mockery::mock('DB');
        $mock_data->shouldReceive('all')->andReturn($data);
        $mock_ctrl= new ContactsBLO;
        $mock_ctrl->select=$mock_data;
        $result=$mock_ctrl->search('manh');    
        $this->assertNotNull($result);
    }

and this is ContacsBLO class:

class ContactsBLO
{

    public $db,$not_allow,$Validation;
    public function __construct(){
        $this->db=new DB;
        $this->not_allow=['"','\'','%'];
        $this->Validation = new ContactValidation;    
    }

    public function search($request=null){
        $length=strlen($request);
        for ($i=0;$i<$length;$i++) {
            $forbidden=$this->not_allow;
            if(in_array($request[$i],$forbidden)){
                return (['messenger'=>'We are not allow special character in your request','old_input'=>$request]);
            }
            else{
                return $data=$this->db->select('*',$request);
             }
        }
    }
}

DB::class(i define connect to data base and define select method:

class DB
{
    public $obj = null;
    public $table = 'contacts';
    public function __construct(){
         $dsn="mysql:host=".HOST."; dbname=".DB_NAME;
         $this->obj = new \PDO($dsn, DB_USER, DB_PASS);
         $this->obj->query("set names 'utf8' ");
    }
    public function select($row=null,$query=null)    {
        $sql='SELECT '.$row.' FROM '.$this->table.' '.$query;
        $data = $this->obj->prepare($sql);
        $data->execute();
        return $data->fetchAll(\PDO::FETCH_CLASS);
    }
}

But when i run xdebug and run this test, $forbidden is null,it mean mock method return real data, not mock data. i dont know why. Anyone can help me! Please!

Upvotes: 0

Views: 69

Answers (2)

The Manh Nguyen
The Manh Nguyen

Reputation: 465

I was change it to:

$mock_data=\Mockery::mock('DB');
$mock_data->shouldReceive('select')->andReturn($data);
$mock_ctrl= new ContactsBLO;
$mock_ctrl->db=$mock_data;
$result=$mock_ctrl->search();

And it is working for me, thank for all help

Upvotes: 0

Borisu
Borisu

Reputation: 848

You never inserted your mock into your class, besides when using the new keyword to create a class instance it's difficult to mock. Your only chance in such cases is to use class alias.
To avoid all this you can pass in the database instance through the ContactsBLO constructor.

class ContacsBLOTest extends TestCase
{   
    public function testSearch()
    {
        $data = ['id'=>1,'name'=>'The Manh','phone'=>'123456566','address'=>'180 cao lo','note'=>''];
        $data = json_decode(json_encode($data));
        $mock_contact = \Mockery::mock(DB::class);  
        $mock_contact->shouldReceive('select')->andReturn($data);
        $Ctrl = new ContactsBLO($mockDB);
        $result = $Ctrl->search('manh');
        $this->assertNotNull($result);
    }
}

class ContactsBLO
{
    public $db;
    public $not_allow;
    public $Validation;

    public function __construct(DB $db) {
        $this->db = $db;
        $this->not_allow = ['"','\'','%'];
        $this->Validation = new ContactValidation;
    }

    public function search($request=null){
        $length=strlen($request);
        for ($i=0;$i<$length;$i++) {
            $forbidden = $this->not_allow;
            if(in_array($request[$i],$forbidden)){
                return (['messenger'=>'We are not allow special character in your request','old_input'=>$request]);
            }
            else{
                return $data = $this->db->select('*',$request);
             }
        }
    }
}

I tested it with this code and it worked fine. Please check if the DB class is imported at the top of your test file. You also have to append Test to all test file names and classes (see above).

Upvotes: 1

Related Questions