如何改进单元测试此功能

时间:2016-05-01 22:24:10

标签: php unit-testing phpunit

我想知道是否有其他单元测试(我的意思是我可以不依赖于测试数据库而进行的其他单元测试),我可以为以下类中的函数getAll执行此操作:

<?php
namespace Example\Model;

use Example\Lib\PdoConnection;

class UserModel {

    private $pdoConn;

    function __construct()
    {
        $this->pdoConn = PdoConnection::getInstance();
    }

    function getAll()
    {
        $arrUsers = array();
        $strSql = "SELECT id, first_name, last_name FROM user";
        $arrData = array();
        try
        {
            $objRes = $this->pdoConn->prepare($strSql);
            $objRes->execute($arrData);
            $objRes->setFetchMode(\PDO::FETCH_ASSOC);
            $arrUsers = $objRes->fetchAll();
        }
        catch(\PDOException $e) {
            error_log($e->getMessage());
        }
        return $arrUsers;
    }   

以下是我测试它的方法:

function testGetAll()
{   
    $stubUserModel = $this->getMockBuilder('Example\Model\UserModel')
    ->disableOriginalConstructor()
    ->getMock();

    $stubUserModel->method('getAll')
    ->willReturn(array(array('id' => 1, 'first_name' => 'First1', 'last_name' => 'Last1'), array('id' => 2, 'first_name' => 'First2', 'last_name' => 'Last2')));

    $this->assertEquals(array(array('id' => 1, 'first_name' => 'First1', 'last_name' => 'Last1'), array('id' => 2, 'first_name' => 'First2', 'last_name' => 'Last2')), $stubUserModel->getAll());       
}

我知道需要更多的测试才能被认为是经过单元测试的,而且我上面写的测试也没用。

我发现很难测试,因为它依赖于类PDOConnection以及预准备语句返回的类(在本例中obj实例化为$ objResult)。这是否意味着我必须重构代码并将PDOConnection依赖项移到此函数之外,并且可能将$ objRes和参数传递给getAll函数以便能够模拟它?或者还有另一种方法可以降低它的可测性?

欢迎所有建议。

由于

1 个答案:

答案 0 :(得分:0)

由于依赖注入,您应该将pdo连接作为构造函数参数传递。然后,您可以考虑模拟连接并确保使用预期参数将预期方法称为预期时间。您可以使用Mockery,Prophecy或phpunit mock对象等库。那么这不是模型,而是提供者或存储库。所以你应该把它叫做UserProvider或UserRepository