次のクラスの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関数の引数を偽装できるようにする必要があることを意味しますか?それをテスト可能にするのに安価な別の方法がありますか?
すべての提案を歓迎します。依存性の注入に
おかげ
依存性注入のために、pdo connectionをコンストラクタparametroとして渡す必要があります。ティーンは、偽の接続をツアーモデルの偽データベース操作に渡します。このオブジェクトをテストすることは、データベースにかなり依存しています。したがって、テストの有効性のポストは、pho metodが期待されるパラメータで呼び出されることをテストすることになります。それから、これはモデルではなくファサードです。それをUserProviderFacade – zioMitch
と呼んでください。データベース抽象化レイヤをモックしないでください。単体テストを書く代わりに、データベースにヒットする統合テストを書くべきです。 http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html –
@Pherserk、それは数日後ですが、あなたの答えは意味があると思います。私はそれを受け入れることができるように答える? –