web-dev-qa-db-ja.com

単体テストと結合

開発者として、クラス間の結合が少ないように努力する必要があります。

ただし、低結合は「結合なし」を意味するわけではないため、コードの柔軟性を許容し、ドメインモデル内で「新規」を使用する必要がある場合があります。 (私は誰もが実際の製品コードでこれを行うと確信しています)

メソッド内で「new」を使用してオブジェクトを作成し、このメソッドを単体テストする必要がある場合、問題が発生しました。オブジェクトをモックできないため、メソッドを単独でテストすることはできません。依存性注入を使用したり、オブジェクトをパラメーターとして送信したりできることはわかっていますが、この明確なケースについては話していません。

これは実際には受け入れられますか?
もっと良い方法はありますか? (私はいつも注入できるわけではありません)
これは単体テストですか、統合テストですか?

PHPの例:

class Car {
   protected $objDoor;
   public function createComponents() {
       $this->objDoor = new Door();
   }
}
4
danidacar

依存性注入

作成するオブジェクトに大きく依存すると思います。返すオブジェクトを作成する場合、それはメソッドの仕様の一部です。その場合、基本的に単体テストを行うことができます。

問題のクラス(新しく使用するクラス)の単体テストも行うので、これが主な問題になることはありません。ただし、オブジェクトを作成し、そのオブジェクトを使用して何らかの処理を行う(副作用が発生する)場合は、インジェクションを使用する必要があります。メソッドのパラメーターとしてコンストラクター呼び出しのすべてのパラメーターを取得する場合、これはさらに当てはまります。メソッドを呼び出す前にオブジェクトを作成し、代わりに参照を指定するだけです。

しかしもちろん、それはオブジェクトが作成されるメソッドが今同じことをしていることを意味します。

そうは言っても、依存性注入を処理するある種の中央メカニズムが必要になります。 symfonyはそのようなものを処理する 依存性注入 コンポーネントを提供します。

コードカバレッジ

コードカバレッジを持つことが重要です。それがどれだけうまくできるかはあなたのプロジェクトに強く依存します。可能な限り、ユニットテストを作成する必要があります。その上、特定の機能をテストする機能テストを使用する必要があります(したがって、必要なクラスの相互作用)。全体として、あなたのニーズに合うはずです。

4
Jim Martens
_  > Is there a better way? (I can't always inject)
_

より良いではありませんが、より簡単で同等です:

inject factory-method/classを使用して新しいドメイン子アイテムを作成したくない場合は、ローカルで保護された仮想ファクトリメソッドを実装できます。

_public class MyClassUnderTest {
   virtual protected MyObjectType createMyObjectType() {return new MyObjectType();}
}
_

new MyObjectType()を直接呼び出す代わりに、このファクトリメソッドを使用します。

テストでは、MyClassUnderTestから継承し、createMyObjectType()をモックコードで上書きするか、createMyObjectType()が呼び出された場合に、モックフレームワークに特別な子オブジェクトを返すように依頼します。

0
k3b