Home > Back-end >  How to write PHPunit test code with external object (having DAO)?
How to write PHPunit test code with external object (having DAO)?

Time:10-30


I'm trying to write test code for monosilic code like below.

Q1. How to write test code which has access to DB?
Q2. How to refactor these code testable?
Q3. Is there any way to write test code with fewer change to production code?

I need your help!
Thanks!!

Example Production Code)

<?
class Sample_Model_Service_A
{
private $_result
private $_options
private $_someValue

    public function __construct($params, $ids, $data) {
        $this->_options = Sample_Model_Service_B::getOption($data);
    }

    private function setSomeValue() { 
    // some code shaping $_params to $someValue with $this->_options
        $this->_someValue= $someValue;
    }

    // want to write test for this function
    // changed this function's logic
    private function setResult() { 
    // some code shaping $_someValue to $result
        $this->_result = $result;
    }

    public function getter() {
        retrn $this->_result;
    }
}
?>

<?
class Sample_Model_Service_B
{
    // get option from DB
    public static function getOption($data) {
        $dao = new Model_Dao_Option();
        $option = $dao->getOption($data['id']);
        return $option;
    }
}
?>

My Test Code so far)

public function testsetResult()
{
// just make sure these variables are defined
$params = $ids = $data = [];
// try to make test for private function
$sample = new Sample_Model_Service_A($params, $ids, $data);
$reflection = new ReflectionClass($sample);

// get Method
$method = $reflection->getMethod('setresult');
$method->setAccessible(true);

// wondering how to get $result
$result = $method->invoke($sample);

// assert
$this->assertSame($result);
}

CodePudding user response:

Mockery solved my issue.

Sample Code)

/**
* @dataProvider sampleProvider
*/
public function testsetResult($sampleData)
{
        // mock Sample_Model_Service_B
        $mockSample_Model_Service_B = Mockery::mock('alias:' . Sample_Model_Service_B::class);
        $mockSample_Model_Service_B->shouldReceive('getOption')->andReturn($sampleData['option']);

        $sample = new Sample_Model_Service_A($sampleData['params'], $sampleData['ids'], $sampleData['data']);
        $sample->setResult();
        $result = $sample->getter();

        // assert
        $this->assertSame($result, $sampleData['result']);
}
  • Related