Как проверить, что метод вызывается с объектом, некоторые поля которого могут быть anyObject (), а другие имеют определенное значение? - PullRequest
0 голосов
/ 20 ноября 2018

Я использую Mockito со ScalaTest.Рассмотрим этот упрощенный пример.

Класс кейса модели:

case class Batch(batchId: Long, 
                 timestamp: Option[LocalDateTime] = Some(LocalDateTime.now),
                 invoicesReceived: Option[Int])

В моем тесте я высмеиваю класс с именем BatchRepository, в котором есть метод с такой сигнатурой:

def create(conn: Connection, batch: Batch): Long

Соответствующий бит тестового кода:

verify(batchRepository, times(1)).create(anyObject(),
  Batch(anyLong(), anyObject(), Matchers.eq(Some(1))))
)

Говорят: : я хочу убедиться, что тестируемый код вызывает метод макетированного репозитория с любым подключением и экземпляром Batchс любым идентификатором и отметкой времени, но invoicesReceived точно равен Some(1).

При использовании Mockito это вообще возможно, и если да, то как?

Рабочий код создает новую серию, которая устанавливает метку времени на текущий момент, поэтому я думаю, что это практически невозможносоздать реальный пакетный объект в тесте для вызова verify() с точно такой же отметкой времени.Так что, по крайней мере, для временной метки мне понадобится anyObject().

Я перепробовал много вариантов, например, упаковал всю серию в Matchers.eq(), но я не нашел ничего, что работает:

Неправильное использование сопоставителей аргументов!Ожидается 2 совпадения, 4 записано [...]

Я был бы рад услышать, что я неправильно использую совпадения, если окажется, что есть какой-то альтернативный способ использовать Mockito для проверки того, что яхочу.10

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

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вы пробовали mockito-scala ?он поддерживает частичные функции как сопоставители, так что вы можете просто написать

verify(batchRepository, times(1)).create(any, argMatching({case Batch(_, _, Some(1)) => }))

или даже лучше, если вы используете идиоматический синтаксис

batchRepository.create(*, argMatching({case Batch(_, _, Some(1)) => })) was called
0 голосов
/ 20 ноября 2018

Проблема в том, что вы пытаетесь verify сделать два вызова одновременно - create и Batch.apply.Не могу этого сделать.

Один из способов сделать то, что вы хотите, это ArgumentCaptor:

val captor = ArgumentCaptor.forClass(classOf[Batch])
verify(batchRepository).create(any(), captor.capture)
captor.getValue should matchPattern {
  case Batch(_, _, Some(1)) => 
}
// or just `captor.getValue.infoReceived shouldBe Some(1)`
...