如何用外部对象(有DAO)编写PHPunit测试代码?

How to write PHPunit test code with external object (having DAO)?


我正在尝试为如下的单体代码编写测试代码。

Q1。如何编写可以访问数据库的测试代码?
Q2。如何重构这些可测试的代码?
Q3.有没有什么方法可以在对生产代码进行较少更改的情况下编写测试代码?

我需要你的帮助!
谢谢!!

示例生产代码)

<?
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;
    }
}
?>

到目前为止我的测试代码)

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);
}

Mockery解决了我的问题。

示例代码)

/**
* @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']);
}