1

在收到评论并弄清楚它是如何工作的之后,我仍然认为:

不过,如果 specs2 提供非消耗性逻辑以及迭代器的消耗性,那就太好了。就像我不直接使用iterator.size方法,而是使用规范的方法,例如:haveSize

我有一个测试,其中有一个代码:

 val ids = for(software <- parser) yield software.productID

 //ids.size must_== 2;

 ids.foreach(x => println(x))

它产生输出:

 1
 2

如果我取消注释 spec2 check ( ids.size must_== 2),它将提供空输出。

看起来 spec2,遍历迭代器(ids),然后我最终得到指向数据末尾的迭代器(空迭代器)。因此我不能再使用这个迭代器了——在接下来的测试中。

Shod spec2/test 框架的行为是这样的?

所以,如果我使用这样的测试(出于某种原因):

  ids.size must_== 2;
  ids.size must_== 2;

它会失败。

//--

这里我们使用迭代器的 size() 方法。所以,我认为有这样的行为是可以的。但是如果使用这样的代码:

Ids.toIterable must haveSize(2); // here we do not use iterator.size() method dirrectly
for(id <- ids) println(id). 

什么都不打印。看来它仍然消耗我的“可怜”迭代器..


找到了解决方法:

  val (it1, it2) = ids.duplicate    

  it1.size must_== 2;
  it2.size must_== 2;

有了这个(转换为列表),它也可以工作(就像评论中建议的那样):

val ids = for(software <- parser.toList) yield software.productID

但这正是 spec2 默认可以使用的(对于类似的方法haveSize)。(我发布了一个错误)。

4

2 回答 2

2

当你写iterator.size must_== 2你自己消耗你的迭代器时,specs2 只接收值2(如果迭代器的大小为 2)。因此,specs2 对此无能为力。

然后你可以要求 specs2 通过写来检查迭代器的大小,iterator must haveSize(2)并期望迭代器不会被消耗。我认为这也不是一个好主意。我认为这iterator must haveSize(2)是合理预期的简写iterator.size must be_==(2),它消耗迭代器。

我的建议是让用户代码决定是否应该消费某些东西。Stream如果您想评估它的大小检查它的元素,您可以保留您的迭代器,或者将其转换为 a :

 val iterator = Seq({println(1); 1}, {println(2); 2}).iterator
 val elements = iterator.toStream

 elements must haveSize(2)
 elements(1) === 2
于 2013-05-05T08:54:03.200 回答
0

An iterator is mutable, and can only be consumed once, in this case by calling .size. The scaladoc has helpful details, and mentions "one should never use an iterator after calling a method on it."

What you seem to need is a collection that's a subtype of Iterable (which contains a foreach method) such as List or Vector. If you are only calling foreach like in the example, all you need to do is surround the for loop in the first line with {..} then add .toIterable or toList, or the following will work.

val ids = parser.map(_.software).toIterable // collection would be the same as parser
ids.size must_== 2;
ids.size must_== 2;
于 2013-05-05T17:58:29.587 回答