Как вы проходите через каждый статус в Scala?
Я пытаюсь перебрать каждое состояние, чтобы проверить, имеет ли ArrayList хотя бы 1 статус ACTIVE и 1 статус INACTIVE.
var active = false;
var inactive = false;
for (item <- reasons.items) {
if(item.status == "ACTIVE")
active = true
if(item.status == "INACTIVE")
}
active must be (true)
inactive must be (true)
Есть ли более чистый способ сделать это? Я пробовал с такими потоками, но не повезло
var active = false;
var stream = reasons.items.toStream
.forEach(item => if(item.status == "ACTIVE") {active = true})
Примечание: причины удерживает предметы (Есть 1 предметов). items содержит отдельные элементы, которые могут быть вызваны как reason.items.get(x).
3 ответа
Другие ответы хорошо объясняют, как этого добиться, используя коллекции Scala. Поскольку похоже, что вы используете ScalaTest, я хотел бы добавить, что вы также можете использовать ScalaTest для циклического перемещения по элементам.
Использование синтаксиса в стиле цикла от инспекторов:
forAtLeast(1, reasons.items) { item =>
item.status must be ("ACTIVE")
}
forAtLeast(1, reasons.items) { item =>
item.status must be ("INACTIVE")
}
Обратите внимание, что инспекторы определяются отдельно от сопоставителей, поэтому вам придется import org.scalatest.Inspectors._
или же extends … with org.scalatest.Inspectors
получить forAtLeast
в сферу.
Если вы хотите избежать синтаксиса стиля цикла от инспекторов, вы можете использовать сокращенный синтаксис инспектора вместе с основанным на отражении have
синтаксис:
atLeast(1, reasons.items) must have ('status "ACTIVE")
atLeast(1, reasons.items) must have ('status "INACTIVE")
Если вы хотите избежать основанного на отражении синтаксиса для have
Вы можете продлить have
синтаксис для поддержки вашего status
собственность напрямую:
def status(expectedValue: String) =
new HavePropertyMatcher[Item, String] {
def apply(item: Item) =
HavePropertyMatchResult(
item.status == expectedValue,
"status",
expectedValue,
item.title
)
}
atLeast(1, reasons.items) must have (status "ACTIVE")
atLeast(1, reasons.items) must have (status "INACTIVE")
Или, если вы предпочитаете be
над have
Вы могли бы продлить be
синтаксис для добавления поддержки active
а также inactive
:
class StatusMatcher(expectedValue: String) extends BeMatcher[Item] {
def apply(left: Item) =
MatchResult(
left.status == expectedValue,
left.toString + " did not have status " + expectedValue,
left.toString + " had status " + expectedValue,
)
}
val active = new StatusMatcher("ACTIVE")
val inactive = new statusMatcher("INACTIVE")
atLeast(1, reasons.items) must be (active)
atLeast(1, reasons.items) must be (inactive)
В примерах, приведенных здесь, выглядит немного глупо определять собственные сопоставители, чтобы сохранить пару слов в утверждении, но если вы напишите сотни тестов об одних и тех же свойствах, может быть очень удобно свести утверждения к одной строке и все еще быть естественно читаемым. Таким образом, по моему опыту, определение таких собственных сопоставителей может иметь смысл, если вы повторно используете их во многих тестах.
Для "по крайней мере 1" вы можете использовать exists
на items
который проверяет заданный предикат и возвращает истину, если хотя бы один из элементов удовлетворяет критериям. Для "АКТИВНЫЙ и НЕАКТИВНЫЙ" вы можете объединить два exists
требует неэффективного подхода с использованием &&.
reasons.items.exists(_.status.equals("ACTIVE")) && reasons.items.exists(_.status.equals("INACTIVE"))`
Чистый подход будет
val active = reasons.items.exists(item => item.status == "ACTIVE")
или короче
val active = reasons.items.exists(_.status == "ACTIVE")
Аналогично для val inactive
, Это имеет проблему итерации по списку дважды (но остановка, как только подходящий элемент найден оба раза в отличие от вашего кода).