3

単体テストに関するさまざまな質問に目を通しましたが、この質問に具体的に答えるものは見つかりません。

次のような関数を含む PHP クラスがいくつかあります。

    static function _setSuspended($Suspended, $UserID)
    {
        try {
            $con = Propel::getConnection();

            $c1 = new Criteria();
            $c1->add(DomainsPeer::USERID,$UserID);

            $update = new Criteria();
            $update->add(DomainsPeer::SUSPENDED,$Suspended);

            BasePeer::doUpdate($c1, $update, $con);

            return true;
        } catch(PropelException $e) {
            return $e->getMessage();
        }
    }

Propel を ORM として使用しています。「モック」と「スタブ」の作成に関するさまざまな単体テストのトピックを読みましたが、上記のような関数をテストする方法を具体的に説明するものは見つかりませんでした。

私の考えは次のようになります。上記の関数をテストする必要があるので、それを呼び出したいと思います。しかし、私がそれを呼び出すと、Propel を ORM として使用し、単体テストの原則に従って、各関数を個別に分離する必要があります。

私はそれを行う方法がわかりません。ここで何が欠けていますか?

4

5 に答える 5

1

Symfony 用の PHPUnit プラグインを構築しているときに、同じ問題に取り組もうとしていました。私はDjango のテスト フレームワークと同じようにアプローチすることになりました— 別のデータベース/接続を使用し、すべてのテストの前にそれを破棄して再構築します。

テスト実行の最初のテストの前に (またはテストで明示的に指示された場合)、テスト データベースを再構築するだけで済むこともわかりました。他のテストの前に、すべてのデータを削除して速度を少し上げます。

于 2011-12-13T18:06:40.593 に答える
1

ORM 構成がテストされないため、ORM をモックしても自信が持てないことがわかりました。また、ORM には、単体テストで誤った信頼を与える可能性がある遠隔効果での多くのアクションがあります。データベース ドライバーをモックしたり、別のインメモリ データベースを提供したりすることで、自分のコードが正しく、ORM をモックするのと同じくらい難しいという確信が得られます。

SQLite は、単体テスト用の優れたメモリ内データベースです。これは、PDO がサポートするデータベース リストにあります。(PDO は Propel 1.3 データベース ドライバーです。) インメモリ データベースを使用したくない場合は、既に記述されている PDO モックを見つけることができるかもしれません。

于 2009-03-23T14:56:51.653 に答える
0

これは、単体テストできない強い依存関係を持つクラスの例です。

別のデータベースへの接続をテストすることはできますが、それは単体テストではなく、統合テストになります。

私が考えるより良い代替案は、必要なすべての異なるメソッドをラップする QueryFactory クラスを用意することです。そうすれば、それをモックできるようになります。

まず最初に、インターフェイスを作成します

interface iQueryFactory
{
    function firstFunction($argument);
    function secondFunction($argument, $argument2);
}

必要なすべての ORM リクエストを含む QueryFactory

class QueryFactory implements iQueryFactory
{
    function firstFunction($argument) 
    {
        // ORM thing
    }

    function secondFunction($argument, $argument2)
    {
        // ORM stuff
    }
}

クエリファクトリの注入によるビジネスロジックがあります

class BusinessLogic 
{
    protected $queryFactory;

    function __construct($queryFactoryInjection) 
    {
        $this->queryFactory= $queryFactoryInjection;
    }

    function yourFunctionInYourBusinessLogique($argument, $argument2) 
    {
        // business logique

        try {
            $this->queryFactory->secondFunction($argument, $argument2);
        } catch (\Exception $e) {
            // log
            // return thing
        }

        // return stuff
    }
}

モックの部分では、例としてモック フレームワークを使用していないことに注意してください (ところで、応答セッターを作成できます)。

class QueryFactoryMock implements iQueryFactory
{
    function firstFunction($argument) 
    {
        if (is_null($argument)) 
        {
            throw new \Exception("");
        } 
        else 
        {
            return "succes";
        }
    }

    function firstFunction($argument, $argument2) 
    { 
        // sutff  
    }
}

最後に、モック実装を使用してビジネス ロジックをテストする単体テスト

class BusinessLogicTest extends PHPUnit_Framework_TestCase 
{
    public function setUp() 
    {
        require_once "BusinessLogic.php";
    }

    public function testFirstFunction_WhenInsertGoodName() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject ->firstFunction("fabien");

        $this->assertEquals($response, "succes");
    }

    public function testFirstFunction_WhenInsetNull() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject->firstFunction(null);

        $this->assertEquals($response, "fail");
    }
}
于 2015-07-08T00:30:41.763 に答える
0

最近、テストに関する Misko Hevery のブログをよく読んでいます。この状況をカバーしています。DI(依存性注入)を使用する必要があります。

私もこれに少し苦労しており、推進力も使用しています。

1 つには、「サスペンド」メソッドをピアではなく「オブジェクト」クラスに移動できます。とにかく、この特定の関数については、これを達成するために静的メソッドを使用する必要はありません。API は次のようになります。

MyObjectPeer::retrieveByPK(1)->suspend();

これは、通常の単体テスト方法でテストできます。

テストする必要があるのが本当にデータベースである場合、実際にテストにDBを含める必要があることがわかります。現在のプロジェクトで ltree と postgis をよく使用していますが、DB に依存するモデル ロジックの単体テストをテストに含める以外に実行する方法は考えられません。

于 2009-03-23T21:06:12.653 に答える