Specs2打破我的测试数据,由于它的方式与迭代器的工作原理(Specs2 breaks my te

2019-10-18 02:43发布

后主动意见,并想出如何它的作品,我仍然认为:

会很好,不过,如果specs2提供非消耗性逻辑,与消费品的迭代器一起。 就像如果我不直接使用iterator.size的方法,但使用规范的方法,如:haveSize

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

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

 //ids.size must_== 2;

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

它产生的输出:

 1
 2

如果我取消SPEC2检查( ids.size must_== 2 ),将与空的输出提供。

这似乎SPEC2,越过迭代器(IDS),然后我结束了迭代器指向数据的末尾(空迭代器)。 因此,我不能再使用这个迭代器 - 在接下来的测试。

SHOD SPEC2 /测试框架,这样的表现?

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

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

它会失败。

// -

这里我们使用迭代器的尺寸()方法。 所以, 我已经得到了这是确定有这样的行为。 但是,如果使用这样的代码:

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 )。 (我已经发布了一个错误 )。

Answer 1:

当你写iterator.size must_== 2你消耗自己的迭代器,specs2只是接收值2 (如果迭代器有大小2)。 因此,有没有什么specs2可以做些什么。

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

我的建议是留给用户代码的决定来控制,如果事情应该被消耗与否。 您可以留下您的迭代器,因为它是,或将其变成一个Stream ,如果你想既评估其规模检查其内容:

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

 elements must haveSize(2)
 elements(1) === 2


Answer 2:

迭代器是可变的,只能通过调用.size一次消费,在这种情况下。 该scaladoc有帮助的细节,并提到“一个不应该使用迭代器调用一个方法就可以了。”

你似乎需要的是一个集合,是可迭代的亚型(包含一个foreach方法)如List或矢量。 如果你只调用的foreach比如上例中,所有你需要做的就是围绕for循环与{..}然后添加.toIterable或toList,或下面的工作的第一线。

val ids = parser.map(_.software).toIterable // collection would be the same as parser
ids.size must_== 2;
ids.size must_== 2;


文章来源: Specs2 breaks my test data, due to the way it works with iterator
标签: scala rspec2