PHPUnit - 模拟回调函数

时间:2015-09-21 12:03:57

标签: php zend-framework2 phpunit zend-db

这是一个使用Zend DB / Tablegateway的函数:

public function listAttestations($sSidx = null, $sSord = null, $iOffset = 0, $iLimit = 0)
{
    try {
        $resultSet = $this->tableGateway->select(
            function (Select $select) use ($sSidx, $sSord, $iOffset, $iLimit) {
                if ($sSidx != null && $sSord != null) {
                    $select->order($sSidx.' '.$sSord);
                }
                $select->join(
                    'f_travclient',
                    'syndic_client_id = f_travclient.travClient_id',
                     array('syndic' => 'nom')
                );
                $select->offset($iOffset);
                $select->limit($iLimit);
            }
        );
        return $resultSet;
    } catch (\Exception $e) {
        throw new \Exception($e);
    }
}

我使用PHPUnit进行单元测试。也许,我不知道如何制作超越我之前方法的功能。我认为这可能有用:

public function testListAttestations()
{
    $resultSet = new ResultSet();

    $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('select'), array(), '', false);

    $mockTableGateway->expects($this->once())
            ->method('select')
            ->with()
            ->will($this->returnValue($resultSet));

    $attestTable = new FMaiAttestationTable($mockTableGateway, $this->adapter, $this->sql);

    $this->assertSame($resultSet, $attestTable->listAttestations('maiAttestation_id', 'ASC', 0, 30));
}

但这并没有更进一步:

function (Select $select) use ($sSidx, $sSord, $iOffset, $iLimit) {

有人能帮帮我吗?感谢。

1 个答案:

答案 0 :(得分:1)

您可以使用returnCallback()

获取和使用任何给出模拟方法的参数
$mockTableGateway->expects($this->once())
        ->method('select')
        ->with()
        ->will($this->returnCallback(function($function) use ($resultSet) {
            // do something with the function, for example:
            if(!is_callable($function)) {
                return NULL;
            }
            call_user_func($function, new Select());
            return $resultSet;
        }));

但是,您可能想重新考虑当前的代码,因为没有必要像这样嵌套编写它。例如,您可以自己获取Select的实例并将其与selectWith()

一起使用
public function listAttestations($sSidx = null, $sSord = null, $iOffset = 0, $iLimit = 0)
{
    try {
        $select = new Select();
        if ($sSidx != null && $sSord != null) {
            $select->order($sSidx.' '.$sSord);
        }
        $select->join(
            'f_travclient',
            'syndic_client_id = f_travclient.travClient_id',
            array('syndic' => 'nom')
        );
        $select->offset($iOffset);
        $select->limit($iLimit);
        $resultSet = $this->tableGateway->selectWith($select);
        return $resultSet;
    } catch (\Exception $e) {
        throw new \Exception($e);
    }
}

在这种情况下,现在可以测试您的方法是否按照您想要的方式放置Select。您可以按照预期的方式在测试中创建另一个Select对象:

    $resultSet = new ResultSet();

    $sSidx = 'maiAttestation_id';
    $sSord = 'ASC';
    $iOffset = 0;
    $iLimit = 30;

    $select = new Select();
    $select->order($sSidx.' '.$sSord);
    $select->join(
        'f_travclient',
        'syndic_client_id = f_travclient.travClient_id',
        array('syndic' => 'nom')
    );
    $select->offset($iOffset);
    $select->limit($iLimit);

    $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway',
        array('selectWith'), array(), '', false);

    $mockTableGateway->expects($this->once())
        ->method('selectWith')
        ->with($select)
        ->will($this->returnValue($resultSet));

    $attestTable = new FMaiAttestationTable($mockTableGateway, $this->adapter, $this->sql);

    $this->assertEquals($resultSet, $attestTable->listAttestations($sSidx, $sSord, $iOffset, $iLimit));

如果模拟方法Select使用的selectWith对象与您创建的方法有任何不同,PHPUnit将在您的测试中抛出错误。