4

データベース内のデータアクセスを管理するクラスをテストしようとしています(基本的にはCRUDです)。私たちが使用しているDBライブラリには、静的呼び出しによって最初にテーブルオブジェクトを取得するAPIがあります。

function getFoo($id) {
  $MyTableRepresentation = DB_DataObject::factory("mytable");
  $MyTableRepresentation->get($id);
  ... do some stuff
  return $somedata
}

...あなたはアイデアを得る。

このメソッドをテストしようとしていますが、DataObjectのものをモックして、(a)テストに実際のdb接続を必要とせず、(b)テストにDB_DataObjectlibを含める必要さえありません。 。

ただし、PHPUnitでは、静的呼び出しを適切に設定するために$ this-> getMock()を取得できないようです。私は持っています...

        $DB_DataObject = $this->getMock('DB_DataObject', array('factory'));

...しかし、テストはまだ未知の方法「工場」を示しています。以前はDB_DataObjectが見つからなかったため、オブジェクトを作成していることはわかっています。今ではできます。しかし、方法はありませんか?

私が本当にやりたいのは、2つのモックオブジェクトを用意することです。1つはテーブルオブジェクトにも返されます。したがって、ファクトリが静的呼び出しであることを指定する必要があるだけでなく、すでに設定した他の指定されたモックオブジェクトを返すことも指定する必要があります。

しばらく前にSimpleTestでこれを実行し(コードが見つかりません)、正常に機能したことを警告として言及する必要があります。

何が得られますか?

[アップデート]

私はそれがexpects()と関係があることを理解し始めています

4

6 に答える 6

2

静的な呼び出しを使用しない方がよいということで、私はあなたの両方に同意します。ただし、DB_DataObjectはサードパーティのライブラリであり、静的呼び出しはコードの使用に関するベストプラクティスであり、私たちのライブラリではないことを忘れたと思います。返されたオブジェクトを直接作成することを含む、オブジェクトを使用する他の方法があります。そのDB_DOクラスを使用しているクラスファイルに、これらのあからさまなinclude/requireステートメントを残すだけです。テストで同じ名前のクラスをモックしようとすると、テストが失敗する(または分離されない)ので、それは残念です-少なくとも私は思います。

于 2008-12-06T15:53:45.507 に答える
2

ライブラリを変更できない場合は、ライブラリへのアクセスを変更します。DB_DataObject::factory() へのすべての呼び出しをコード内のインスタンス メソッドにリファクタリングします。

function getFoo($id) {
  $MyTableRepresentation = $this->getTable("mytable");
  $MyTableRepresentation->get($id);
  ... do some stuff
  return $somedata
}

function getTable($table) {
  return DB_DataObject::factory($table);
}

これで、テストしているクラスの部分的なモックを使用して、getTable() でモック テーブル オブジェクトを返すことができます。

function testMyTable() {
  $dao = $this->getMock('MyTableDao', array('getMock'));
  $table = $this->getMock('DB_DataObject', ...);
  $dao->expects($this->any())
      ->method('getTable')
      ->with('mytable')
      ->will($this->returnValue($table));
  $table->expects...
  ...test...
}
于 2010-07-19T22:20:36.790 に答える
1

これは、コードの依存関係の良い例です。設計により、実際のクラスではなくモックに注入することが不可能になっています。

私の最初の提案は、静的呼び出しではなくインスタンスを使用するようにコードをリファクタリングすることです。

于 2008-12-05T16:44:22.753 に答える
0

PHPUnit MockFunction拡張機能とrunkitを使用すると、静的メソッドをモックすることもできます。モンキーパッチであるため、極端な場合にのみ使用する必要があるため、注意してください。優れたプログラミング手法に取って代わるものではありません。

https://github.com/tcz/phpunit-mockfunction

于 2011-06-09T20:48:05.650 に答える
0

DB_DataObject クラスに欠けている (または欠けている) ものは、ファクトリ メソッドを呼び出す前に、準備された db オブジェクトを渡すセッターです。そうすれば、必要に応じてモックまたはカスタム db オブジェクト (同じインターフェイスを持つ) を渡すことができます。

テストのセットアップで:

 public function setUp() {
      $mockDb = new MockDb();
      DB_DataObject::setAdapter($mockDb);
 }

factory() メソッドは、モック化された DB インスタンスを返す必要があります。クラスにまだ統合されていない場合は、おそらく factory() メソッドもリファクタリングして機能させる必要があります。

于 2008-12-05T17:04:42.960 に答える
0

テスト ケースに DB_DataObject のクラス ファイルが必要ですか。PHPUnit がオブジェクトをモックしようとする前にクラスが存在しない場合、このようなエラーが発生する可能性があります。

于 2008-12-08T21:11:48.920 に答える