2011-12-23 16 views
12

私はインターフェイスを継承するクラスを作成しています。クライアントコードは、そのインターフェース用に作成され、クラスはそれをサポートするように記述されます。アイデアは、後でそのインタフェース用の他のクラスを作成し、それらの2つの異なるクラスのオブジェクトを完全に交換可能にすることです。最初のクラスのテストクラスを作成するのではなく、インターフェイスのクラスを作成したいと思います。PHPUnit - インターフェイスのテストクラスを作成し、ファクトリを使用してオブジェクトをテストする

私の計画では、コンストラクタ用のファクトリオブジェクトを取得するテストクラス(依存関係注入)を作成し、そのファクトリを使用してテスト対象クラスの新しいインスタンスを作成しました。

そのようにして、ClassAをテストしたければ、ClassAFactoryオブジェクトをテストクラスのコンストラクタに渡すことができました。クラスBをテストしたい場合、ClassBFactoryオブジェクトを渡します。両方のクラスは互換性があるように設計されています。パブリックメソッドのみがテストされているので、理想的です。

しかし、コンストラクタのテストはどうですか?抽象テストクラスを作成し、抽象テストクラスを継承するクラスにコンストラクタテストを組み込む方が良いでしょうか(異なるクラスは異なる方法でインスタンス化できますか)

私は最初のアイデアを使用していた場合、私は同じように、私は各クラスのテストクラスがテストされている必要があります推測:

class ClassATest extends [PHPUnit test case] 
{ 
    $myFactory = new ClassAFactory(); 
    $myTest = new ClassTest($myFactory); 

    $myTest->test1(); 
    $myTest->test2(); 
    //etc. 
} 

これについて移動する最良の方法は何ですか?私は一般的なテストをしたいので、共通のインターフェースを実装するために新しいクラスを書くときに、他のクラスと同じテストのオブジェクトを置くことができます。しかし、異なるクラスが異なるコンストラクタを持つことを見ると、おそらく抽象クラスを作成し、新しいオブジェクトごとに拡張する方が良いでしょうか?どう思いますか?

答えて

6

あなたの計画を再検討する必要があると思います。インターフェースをテストすることはできません。なぜなら、インターフェースは単にAPIを定義して機能を定義せず、テスト機能をテストするだけです。あなたに役立つ例を教えてください。 「メッセージング」インターフェースを持っているとします。したがって、EmailMessagerとSMSMessagerを実装します。ここでは、受信者(電子メールアドレス)を検証したり、電子メールクラスなどに送信を委任するなど、その作業を確実に行うために必要なEmailMessagerの場合とは別に、これらを個別にテストする必要があります。

+1

この特定の例では、クラスはメーリングリストの受信者を表します。彼らは仕事をする方法が異なりますが、クライアントから同じデータを受け取り、同じ結果を返します。完全に交換可能です。そのインタフェースを使用する異なるクラスのオブジェクトがクライアントコード内で互換性がある場合、それらもテストコード内で互換性があるはずです。だから私がインターフェイスをテストしたいと言うと、そのインターフェイスを使用するクラスをテストするために、そのインターフェイスにテストを書きたいと思っています。それはあなたに理にかなっていますか? –

+1

いいえ、それはまだ意味をなさない。それは私が働くインターフェースを理解する方法ではありません。共通コードを実装するインタフェースではなく、抽象基本クラスが必要な場合があります。私はあなたのクラスについて、データ以外に何が違うのか分かりません。 – liquorvicar

+0

MailChimpRecipientはMailingListRecipientインターフェイスを使用します。クライアントコードは、受信者オブジェクトの電子メールアドレスと名前のプロパティを設定し、メソッドを呼び出して追加することで、リストに誰かを追加します。今、MailChimpクラスのそのメソッドは、MailChimp APIを使って追加します。将来、自分のメーリングリストをホストしたい、あるいは別のプロバイダを使用したいと思ったら、MailingListRecipientインターフェイスを使用する別のクラスでクラスを切り替えることができます。そのクラスは受信者を追加するために全く異なる処理を行うかもしれませんが、それでも同じデータが必要です。 –

6

ファクトリを必要とせずに各サブクラスが設定するプロパティを使用して、すべてのテストメソッドで抽象テストケースを作成できます。すべての実装が必要とする固定された品質をテストできます。

abstract class IAdderTestCase extends PFTC 
{ 
    function testAdd() { 
     self::assertEquals(5, $this->fixture->add(2, 3)); 
    } 
    ... 
} 

class BasicAdderTest extends IAdderTestCase 
{ 
    function setUp() { 
     $this->fixture = new BasicAdder(); 
    } 
} 

PHPUnitは、各テストメソッドの前にsetUp()を呼び出します。各具体的なサブクラスに追加されたすべての継承されたテストメソッドを追加する必要があります。コンストラクタをテストします。

+0

ありがとう!それは、それぞれの異なるサブスクラスに対してsetUpメソッドを変更することができるので、最良の方法です。 –

関連する問題