我知道这是一个简单的,但我无法弄清楚订单的错误。
<?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
循环中接下来调用的顺序有关,我只能弄明白它需要的是什么......
答案 0 :(得分:3)
这里似乎有很多错误:
$this->next()
内呼叫StringIteratorTest::testTraverse()
。此方法没有此类next()
方法。该方法属于StringIterator
类。这应该是一个致命的错误。 StringIterator
课程中运行,您仍然无需在next()
循环内调用foreach
。 foreach
调用所有Iterator
- 定义的方法本身。这就是重点。在next()
内拨打foreach
只会产生跳跃位置的效果。 rewind()
方法不正确。它将位置设置为负值。字符串中没有负面位置。如果你打电话给current()
,你会收到一个错误,因为它试图调用$_string[-1]
,但这不存在。 valid()
方法也不正确,因为它只检查位置是否超出上限,而不是下限。这就是valid()
返回TRUE
的原因,即使您的rewind()
方法将位置设置为无效状态。 testValid()
方法应该已经捕获了这个,但该函数实际上并未测试valid()
方法。它只是创建一个新对象而不做任何事情。 testRewind()
方法中很糟糕。您应该调用valid()
并检查它是否返回“B”,而不是检查current()
,这是字符串中的第一个字符。 rewind()
方法的主要功能是将对象的内部指针重置回到开头,因此您应该明确地测试它。