2

これは単純なことだと思いますが、順序がどこで間違っているのかわかりません。

<?php

class StringIterator implements \Iterator
{
private $_string;
private $_length;   
private $_position;


public function __construct($string)
{
    if(empty($string))
    {
        throw new \InvalidArgumentException(sprintf('The specified string is empty'));
    }//end if

        $this->_string = $string;
        $this->_length = strlen($this->_string);
        $this->rewind(); //setting the initial position instead of having it all over the place.

}//end func 

public function current()
{
 return $this->_string[$this->_position];

}//end func

public function key()
{
    return $this->_position;
}//end func



public function rewind()
{
    $this-> _position = -1;
}//end func


public function next()
{
    $this-> _position++;
}//end func


public function valid()
{   //why is it that your doing this instead of...
/*
*   return isset(this->_string[this->_position]);
*
*
*/
    return $this->_position < $this->_length;
}//end func

}//クラス終了

TEST CLASS
<?php

require_once __DIR__. '/../src/Iterators/StringIterator.php';

class StringIteratorTest extends PHPUnit_Framework_TestCase
{
    //each method must begin with TEST
public function testInitializing()
{

    $iterator = new \Iterators\StringIterator("Hello World");

    $this->assertEquals(true,$iterator->valid()); 


}//end func

/**
*   @expectedException InvalidArgumentException
*/
public function testInitException()
{

$iterator = new \Iterators\StringIterator("");

}//end func


public function testTraverse()
{
    $string ="Hello World";
    $iterator = new \Iterators\StringIterator($string);
    $count =0;

    $iterator->rewind();
    //test to make sure the next() runs.


    //The iterator interface defines the method Key key()= $key
    //Iterator::current() = $char (gets the current value at the position)
    foreach($iterator as $key=>$char)
    {
        $this->assertEquals($count,$key);
        $this->assertEquals($string[$count],$char);
        ++$count;
         $this->next();
    }//end 4e

}//end func

//tests that the internal pointer (it) is at a valid position in that container that is being iterated
public function testValid()
{
$iterator = new \Iterators\StringIterator($string);

}//end func

//tests the rewind method back to the start of the container.

public function testRewind()
{
$string="Bye";

$iterator = new \Iterators\StringIterator($string); 


for( $i = 0; $i< strlen($string) + 1; ++$i){

$iterator->next();

}//end for
$this->assertEquals(false,$iterator->valid());
$iterator->rewind();
$this->assertEquals(true,$iterator->valid());

}


}

問題: テスト ( ) を実行すると、実際のテスト コンポーネントのループ内とループ内にphpunit testエラーがあると表示されます。current() (return line)foreach

foreach($iterator as $key=>$char)
{
    $this->assertEquals($count,$key);
    $this->assertEquals($string[$count],$char);
    ++$count;
    $this->next();
}//end 4e

私の調査から、foreachループで次に呼び出す順序と関係があることがわかっています。必要なものを正確に把握できます..

4

1 に答える 1

4

ここには多くの間違いがあるようです:

  • $this->next()以内に電話していますStringIteratorTest::testTraverse()。このメソッドにはそのようなメソッドはありませんnext()StringIteratorそのメソッドはクラスに属しています。これは致命的なエラーです。
  • このコードクラス内で実行されていたとしても、ループ内StringIteratorから呼び出す必要はありません。定義されたすべてのメソッド自体を呼び出します。それが要点です。内で呼び出すと、位置をジャンプする効果があります。 next()foreachforeachIteratornext()foreach
  • あなたのrewind()方法は正しくありません。位置を負の値に設定しています。文字列に負の位置はありません。これを呼び出すと、存在しない current()を呼び出そうとしているため、エラーが発生します。$_string[-1]
  • valid()位置が上限を超えていないことを確認しているだけで、下限を超えていないため、この方法も正しくありません。これが、メソッドが位置を無効な状態に設定している にもかかわらず、valid()が返される理由です。TRUErewind()
  • testValid()メソッドはこれをキャッチする必要がありますが、その関数は実際にはメソッドをテストしていませんvalid()。新しいオブジェクトを作成するだけで、何もしません。
  • あなたのテスト方法論は方法が悪いtestRewind()です。をチェックするのではなく、valid()呼び出しcurrent()て、文字列の最初の文字である「B」が返されるかどうかをチェックする必要があります。このメソッドの主な機能はrewind()、オブジェクトの内部ポインタを先頭にリセットすることなので、明示的にテストする必要があります。
于 2013-01-24T22:16:36.477 に答える