3

依存性注入コンテナーの単体テストを行っています。

最も基本的なレベルでは、オブジェクト グラフの作成が正しく行われていることをテストしています。これは、DIC にロードされたリフレクションとルールを組み合わせて使用​​します。

DIC はクラス定義を使用して動作しますが、モックの依存関係のない性質のために、モックがこのタスクには適していないと考えるのは正しいですか?

モックを使用しない場合、私のテストの 1 つが次のようになります。

public function testObjectGraphCreation() {
    $a = $this->dic->create('A');
    $this->assertInstanceOf('B', $a->b);
    $this->assertInstanceOf('C', $a->b->c);
    $this->assertInstanceOf('D', $a->b->c->d);
    $this->assertInstanceOf('E', $a->b->c->e);
    $this->assertInstanceOf('F', $a->b->c->e->f);
} 

(明らかに、この連鎖と公開依存関係はテストのためだけにあります)

そして、これを機能させるためにいくつかのクラスを定義しました:

class A {
    public $b;

    public function __construct(B $b) {
        $this->b = $b;
    }
}

class B {
    public $c;

    public function __construct(C $c) {
        $this->c = $c;
    }
}

class C {
    public $d;
    public $e;

    public function __construct(D $d, E $e) {
        $this->d = $d;
        $this->e = $e;
    }
}


class D {

}
class E {
    public $f;
    public function __construct(F $f) {
        $this->f = $f;
    }
}

class F {}

このテストの性質上、生成されたモックをこれに使用できないと考えるのは正しいですか?

4

2 に答える 2

1

これは、DIシステム全体を一度にテストする統合テストのように見えます。代わりに、システムが作成するオブジェクトではなく、システムの一部をモックできる場所を確認してください。関係するクラスを見ずに、私は知識に基づいた推測をすることはできません。

PHPUnitのモックオブジェクトを使用することはおそらくできませんが、同じことを行う独自の1回限りのモックを作成することはできます。たとえばDatabase::setPassword、コンテナから取得した値を使用してプロパティの設定をテストするには、モックDatabaseクラスを作成し、パスワードをコンテナに入れて、コンテナにオブジェクトの作成を依頼します。

class MockDatabase {
    public $passwordSet = false;
    public function setPassword($password) {
        if ($password != 'password') {
            throw new InvalidArgumentException('Expected "password"');
        }
        $this->passwordSet = true;
    }
}

...

function testInjectProperty() {
    $container = Container::create(array(
        'password' => 'password',
    ));
    $database = $container->create('MockDatabase');
    self::assertTrue($database->passwordSet);
}
于 2012-09-22T22:18:39.047 に答える
1

あなたは正しいです。これは非常にテストしにくいコードです。

代わりに、適切な DI の方法は、これらのオブジェクトを、それらを必要とするオブジェクト/メソッドに注入することです。

A::__construct(B $b) { $this->b = $b; }

例えば。

于 2012-09-22T11:03:27.280 に答える