2016-05-01 1 views
0

Я хочу знать, есть ли другие модульные тесты (я имею в виду другие модульные тесты, которые я могу сделать, не полагаясь на тестовую базу данных), которые я могу сделать для функции 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 as и аргумент функции getAll, чтобы быть в курсе? или есть другой способ, который является менее дорогостоящим, чтобы сделать его пригодным для тестирования?

Все предложения приветствуются.

Благодаря

+0

Из-за инъекции зависимостей вы должны передать pdo-соединение как конструктор parametro. Подросток передает издеваемое соединение с моделью тура, притворяющейся в базе данных operazioni. Тестирование этого объекта вполне зависит от базы данных. Таким образом, пост эффективности теста будет проверять, что pho-методы вызываются с ожидаемыми параметрами. Тогда это Фасад, а не модель. Назовите его UserProviderFacade – zioMitch

+0

Не следует издеваться над уровнем абстракции базы данных. Вместо написания модульного теста лучше написать интегрированный тест, который попадет в базу данных. http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html –

+0

@Pherserk, прошло уже пару дней, и я понял, что ваш ответ имеет смысл, вы можете добавить его как ответ, чтобы я мог его принять? –

ответ

0

Благодаря инъекции зависимостей, вы должны пройти соединение PDO в качестве параметра конструктора. Затем вы можете подумать о том, чтобы издеваться над соединением и убедиться, что ожидаемые методы называются ожидаемым временем с ожидаемыми параметрами. Вы можете использовать такие библиотеки, как Mockery, Prophecy или phpunit mock objects. Тогда это не модель, а поставщик или репозиторий. Поэтому вы должны называть его UserProvider или UserRepository