2013-05-05 1 views
1

ПОСЛЕ ЧЕГО КОММЕНТАРИИ И выясняли, как это работает, я все еще думаю:Specs2 ломает мои тестовые данные, из-за, как он работает с итератора

Было бы хорошо, хотя, если specs2 обеспечивает нон расходными логики, вдоль с расходными материалами для итераторов. Как, если я не использую iterator.size метод напрямую, метод , но использовать Спекуляции, как: haveSize

У меня есть тест, который имеет код:

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

//ids.size must_== 2; 

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

It производит вывод:

1 
2 

Если я раскомментировать spec2 чек (ids.size must_== 2), это обеспечит пустой выход ,

Кажется, spec2, перебирает итератор (ids), а затем я заканчиваю итератором, который указывает на конец данных (пустой итератор). Таким образом, я больше не могу использовать этот итератор - в следующих тестах.

Shod spec2/test framework ведут себя так:

Так что, если я использую тест, как это (по некоторым причинам):

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). 

Ничего не печатает. Кажется, он по-прежнему потребляет мой 'плохой' итератор ..


I found обходным:

val (it1, it2) = ids.duplicate  

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

И с этим (преобразовать в список), он также будет работать (как было предложил в комментариях):

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

Но это именно то, что spec2 можно использовать по умолчанию (для методов, как haveSize). (я разместил bug).

+1

Почему бы не конвертировать итератор в список? – Antimony

+0

это первое решение, с которым я столкнулся. просто не ожидал и задавался вопросом, почему тест показывает мне правду, но данные пустые послесловия – ses

+0

может быть логичным для spec2 для wok с копией итератора пользователя, но не с оригинальным – ses

ответ

2

Когда вы пишете iterator.size must_== 2, вы потребляете себе итератор, specs2 просто получает значение 2 (если итератор имеет размер 2). Поэтому ничего особенного в этом нет.

Тогда вы могли бы спросить 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 
+0

Получил это. Я не ожидал, что size() будет методом итератора. Я думал, что это метод spec2 сверху/связанный с itarator. – ses

+0

Ids.toIterable must haveSize (2); для (id <- id) println (id). Ничего не печатает. Кажется, он по-прежнему потребляет мой «плохой» итератор. – ses

+0

Было бы неплохо, если бы specs2 обеспечивал не потребляемую логику, а также расходную. Например, если я не использую метод iterator.size напрямую, но используйте метод specs: hasSize – ses

0

Итератор изменчива, и может употребляться только один раз, в этом случае, вызвав .size. scaladoc содержит полезные сведения и упоминает «никогда не следует использовать итератор после вызова метода на нем».

Возможно, вам нужна коллекция, которая является подтипом Iterable (который содержит метод foreach), например List или Vector. Если вы только вызываете 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; 

 Смежные вопросы

  • Нет связанных вопросов^_^