2

セッション管理クラスと関連する単体テストを構築しています。クラスを$_SESSIONのグローバル状態から分離するために、非常に単純なクラスを使用して、クラスとセッションデータ間のバインディングを管理しています。

Bindingクラスのソース全体は次のとおりです。

class Binding implements iface\Binding
{
    public function &getNamespace ($namespace)
    {
        return $_SESSION [$namespace];
    }
}

消費するSessionクラスには、次のものがあります。

protected function initStorage ()
{
    // Check that storage hasn't already been bound to the session
    if ($this -> storage === NULL)
    {
        // Attempt to start the session if it hasn't already been started
        if (($this -> sessionId () !== '')
        || ((!$this -> headersSent ())
        && ($this -> startSession ())))
        {
            // Bind the storage to the session
            $this -> storage    =& $this -> binding -> getNamespace ($this -> namespace);
            // Make sure the session is in a usable state
            if (!$this -> hasData ())
            {
                $this -> reset ();
            }
        }
        else
        {
            // We couldn't start the session
            throw new \RuntimeException (__METHOD__ . ': Unable to initiate session storage at this time');
        }
    }

    return $this;
}

sessionId、headersSent、startSessionは、「テストシーム」として機能する単純な1行の関数であり、PHPUnitのモックに簡単に置き換えることができます。

テストを書いているときに、セッションをクラスから切り離すだけでなく、モックバインディングクラスを使用してより多くのことができることに気付きました。また、実際に内部を公開しなくても、クラスの非公開プロパティを監視する方法として使用できることもわかりました。状態、したがってクラスを脆弱にします。クラスは配列を直接操作するのではなく、配列への参照を操作するため、参照されている配列を観察できます。

PHPUnitのモックAPIでこれを実行したいと思っていましたが、その方法がわかりません。

次のような配列を返すモックを作成できることはわかっています。

$mock = $this -> getMock ('iface\Binding');

$mock -> expects ($this -> any ())
      -> method ('getNamespace')
      -> will ($this -> returnValue (array ()));

ただし、毎回異なる配列を返すため、状態の変化を観察するのには役立ちません。必要なのは、毎回同じ配列への参照を返すモックです。

最後に、実際のBindingクラスの代わりにクラスを作成し、代わりにそれを使用します。

class BindingMock implements iface\Binding
{
    protected $storage = array ();

    public function &getNamespace ($namespace)
    {
        return $this -> storage [$namespace];
    }
}

このクラスを使用すると、Sessionクラスで非公開状態を公開しなくても、ストレージ配列の内容を確認できるため、SessionAPIで何かを呼び出す前後の$storageの内容を調べることができます。この手法を使用したテストの例を次に示します。

public function testCreateItem ()
{
    $storage    =& $this -> binding -> getNamespace ('unittest');
    $this -> assertEmpty ($storage);
    $this -> object ->  createItem ('This is a test', 'test');
    $this -> assertNotEmpty ($storage);
    $this -> assertEquals ('This is a test', $storage ['test']);
}

PHPUnitを使用して代替クラスを生成できるようにしたいと思いますが、PHPUnitで同じことを実現する方法がない限り、単体テスト専用の追加クラスを作成するのは間違った方法のようです。

4

1 に答える 1

0

ArrayObject内部配列をテストに公開するを返すこともできると思いますが、この場合は、配列を公開しないようにすることをお勧めしますBinding。代わりに、Bindingインターフェイスは、他の高レベルの操作とともに値を取得、設定、およびクリアするためのメソッドを提供する必要があります。次に、生の配列を返すものではなく、これらの呼び出しを予期するモックオブジェクトを渡すことができます。

于 2012-08-10T04:29:36.370 に答える