1

PHPunitでコードをテストしています。私のコードには、名前、年齢、カウント、およびランダムによる順序付け方法がいくつかあります。カウントによるソートの実装とテストの下。これらはかなり些細なことです。

class Cloud {
  //...
  public function sort($by_property) {
    usort($this->tags, array($this, "cb_sort_by_{$by_property}"));
    return $this;
  }

  private function cb_sort_by_name($a, $b) {
    $al = strtolower($a->get_name());
    $bl = strtolower($b->get_name());
    if ($al == $bl) {
      return 0;
    }
    return ($al > $bl) ? +1 : -1;
  }

  /**
   * Sort Callback. High to low
   */
  private function cb_sort_by_count($a, $b) {
    $ac = $a->get_count();
    $bc = $b->get_count();
    if ($ac == $bc) {
      return 0;
    }
    return ($ac < $bc) ? +1 : -1;
  }
}

テスト済み:

  /**
   * Sort by count. Highest count first.
   */
  public function testSortByCount() {
    //Jane->count: 200, Blackbeard->count: 100
    //jane and blackbeard are mocked "Tags".
    $this->tags = array($this->jane, $this->blackbeard);

    $expected_order = array("jane", "blackbeard");
    $given_order = array();

    $this->object->sort("count");

    foreach($this->object->get_tags() as $tag) {
      $given_order[] = $tag->get_name();
    }

    $this->assertSame($given_order, $expected_order);
  }

でも今、「ランダムな順序付け」を追加したい

  /**
   * Sort random.
   */
  public function testSortRandom() {
    //what to test? That "shuffle" got called? That the resulting array
    // has "any" ordering?
  }

実装は、0、-1、または +1 をランダムに返すコールバックの呼び出しshuffle($this->tags)から何でもかまいません。usortパフォーマンスは問題ですが、テスト容易性はより重要です。

配列がランダムに並べられたことをテストする方法は? 私の知る限り、のようなグローバルメソッドをスタブ化するのは非常に困難shuffleです。

4

3 に答える 3

1

シャッフルを使用していると仮定すると、メソッドは次のようになります

sortRandom() {
 return shuffle($this->tags);
}

キーがシャッフルされているかどうかをテストする必要はありませんが、配列がまだ返されているかどうかをテストします。

function testSortRandom(){
    $this->assertTrue(is_array($this->object->sortRandom()));
}

PHPコアコードではなく、コードをテストする必要があります。

于 2015-01-28T16:06:57.543 に答える
0

これは、意味のある意味で実際には不可能です。少数のアイテムしかないリストがある場合、ランダムで並べ替えると、特定のフィールドで並べ替えられているように見える可能性が十分にあります (そして、たまたま、並べ替えと同じ順序になる可能性があります)。要素が多すぎない場合、他のフィールドはかなり高くなります)

ソート操作の単体テストは、操作が実際にデータを操作しないかどうかを尋ねると、少しばかげているように思えます。何かが意図したとおりに機能することを実際に測定しているためではなく、それのための単体テストのように感じます。

于 2013-01-02T21:12:21.937 に答える
0

これをグローバルラッパーで実装することにしました:

class GlobalWrapper {
  public function shuffle(&$array);
    shuffle($array);
  }
}

shuffle並べ替えでは、そのラッパーを介して呼び出します。

public function sort($by_property) {
  if ($by_property == "random") {
    $this->global_wrapper()->shuffle($this->tags);
  }
  //...
}

次に、テストでそれをモックしGlobalWrapper、関心のあるグローバル関数のスタブを提供します。この場合、私が興味を持っているのは、メソッドが出力するものではなく、メソッドが呼び出されることだけです[1]。

 public function testSortRandomUsesShuffle() {
   $global = $this->getMock("GlobalWrapper", array("shuffle"));
   $drupal->expects($this->once())
     ->method("shuffle");
   $this->object->set_global_wrapper($drupal);

   $this->object->sort("random");
 }

[1] 実際には、このラッパーにも単体テストがあり、パラメーターと参照による呼び出しを行うという事実をテストしています。また、このラッパーはDrupalWrapper、サード パーティ (Drupal) が提供する特定のグローバル関数をスタブできるように、既に実装されています (および呼び出されています)。この実装により、 を使用してラッパーを渡し、 を使用してset_drupal()それを取得できdrupal()ます。上記の例では、これらset_global_wrapper()を および と呼び global_wrapper()ました。

于 2013-01-03T09:42:21.773 に答える