0

私は小さなクラスの単体テストに取り組んでいます。私はこのクラスを使用して PHPUnit に取り掛かり、将来私が作成するより大きなコードを適切にテストできるようにしています。

テストしようとしている次のコードを検討してください。

/**
 * Registers a starting benchmark tick.
 *
 * Registers a tick with the ticks registry representing the start of a benchmark timeframe.
 *
 * @param string $id The identifier to assign to the starting tick.  Ending tick must be the same.
 * @return bool Returns TRUE if a tick was registered successfully or FALSE if it was not.
 * @since 0.1
 */
public function start($id)
{
    $this->tick($id . "_start");
    if($this->getStart($id) != false) {
        return true;
    }
    return false;
}

/**
 * Retrieves a registered start tick.
 *
 * Checks to see if a start tick is registered.  If found the microtime value (as a float) is
 * returned, otherwise FALSE is returned.
 *
 * @param string $id The identifier to lookup the tick under.
 * @return mixed The microtime (as a float) assigned to the specified tick or FALSE if the tick
 * start hasn't been registered.
 * @since 0.1
 */
public function getStart($id)
{
    if(isset($this->ticks[$id . "_start"])) {
        return $this->ticks[$id . "_start"];
    }
    return false;
}

以下は実際のテストコードです。

public function testBadStartTick()
{
    $this->assertFalse($this->bm->start("What_Invalid_Key_Fits_Here?"))
}

問題は、このテスト関数は、true何度返そうとしても常に返されることfalseです。null 値、300 文字以上のキー、空の配列、さらには新しいオブジェクトのインスタンスを指定しようとしました。いずれの場合も、PHP は中断するか、なんらかの警告をスローします。PHP が壊れない場合、私の値は、PHP が配列キーで受け入れる何かに変換され、$this->assertFalse()..

可能な限り多くのコード カバレッジを実現したいと考えています。

私の質問は、現在のコードを考えると、これらのメソッドがfalse通常の操作で戻るかどうかです。

私はテキストを追加しているので(これは管理目的です)、私が何を与えるかに関係なく、PHPが受け入れるある種のキーを常に提供していると考えています$id

何かご意見は?

前もって感謝します!

4

2 に答える 2

0

コードを編集して、データstartを使用する前に受信を確認するのはどうですか?

public function start($id)
{
    if ($id !== null) { // perhaps more validation is needed?
        $this->tick($id . "_start");
        if($this->getStart($id) != false) {
            return true;
        }
    }

    return false;
}

public function getStart($id)
{
    if(isset($this->ticks[$id . "_start"])) {
        return $this->ticks[$id . "_start"];
    }
    return false
}

次に、次のようにテストできます。

public function testBadStartTick()
{
    $this->assertFalse($this->bm->start(null))
}
于 2014-05-07T19:21:16.467 に答える
0

これを行うには、モックを使用する必要があります。

完全なカバレッジを得るには、この 2 つの部分を実行する必要があります。

しかし、あなたはこれをしなければならないでしょう

public function testBadStartTick()
{
    $bm = $this->getMock('bm', array('getStart'));

    $bm->expects($this->any())
         ->method('getStart')
         ->will($this->returnValue(false));

    $this->assertFalse($bm->start("What_Invalid_Key_Fits_Here"))
}

もちろん、bm を実際のクラス名に置き換えます (名前空間が必要な場合)。このように、そのテストに対してのみ getStart の機能をモックし、結果がどうなるかをテストできます。

もちろん、完全なカバレッジが必要で、必要なものすべてをテストする場合も同様です

public function testGoodStartTick()
{
    $this->assertTrue($this->bm->start("What_Invalid_Key_Fits_Here"))
}

これにより、すべてがうまくいくかどうかパスがテストされます。もうそこをモックしないので、実際の getStart 関数を使用します。

public function testMissingStartTick()
{
    $this->assertFalse($this->bm->getStart("What_Invalid_Key_Fits_Here"));
}

これにより、他の関数とは無関係に getStart() がテストされ、そのためキーが存在せず、false が返されます。

testGoodStartTick() でテストするため、個別にテストする必要のない真のパス

編集: 人々がコメントで言ったように、実行されないコードを持つことは決して賢明ではありません。そこにチェックがあったので、 tick() は時々配列にキーを追加しない魔法を行うかもしれないと思いましたが、あなたのコメントからそうではないことを理解しています。実際、あなたの場合、私の答えは正しいものではなく、常に正しいことがわかっているコードを削除するという提案に従うのが最善です。

于 2014-05-07T19:53:33.880 に答える