Хорошие практики написания и модульного тестирования Утилиты в Scala - PullRequest
0 голосов
/ 18 февраля 2019

В определенных ситуациях вам нужно иметь несколько служебных методов, которые требуются для разных классов.Чтобы разрешить эту ситуацию, вы создаете объект Util, в который вы помещаете все эти методы

object AggregatorUtil {
  def aggregateValues(list : List[BigDecimal]) = //some logic...
}

// Import everything in the Utilities object
import AggregatorUtil._

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

Чтобы снова решить эту проблему, единственное решение, которое пришло на ум, было Извлечение функциональности из черты и затем насмешка над чертой.

Пожалуйста, дайте мне знать, если есть какой-либо другой подход кобработка и тестирование утилитарных методов, и какой из них более чистый.

Заранее спасибо !!!

Примечание: -Я использую scalatest и mockito в моем проекте.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Я в основном высмеиваю Test-Implementation, который нахожу более читабельным, и вам не нужно изучать фальшивые рамки.

Вот пример:

Интерфейс:

trait DataRepo {

  def persist(data: DataObject): Future[DataObject]

  def idents(): Future[List[String]]

  def insertData(dataCont: DataObject): Future[Int]
  ...
}

Mocked Interface:

object DataRepoMock extends DataRepo {

  def persist(data: DataObject): Future[DataObject] = ??? // only implement when needed

  def idents(): Future[List[String]] = Future.successful((0 to 10).map(_=>Random.nextInt(100)))

  def insertData(dataCont: DataObject): Future[Int] = Future.successful(Random.nextInt(100))
  ...
}

Вы также можете использовать все вкусности Scala, такие как Pattern Matching, чтобы заставить Mock по-разному реагировать на ввод.

Вот примерчто это не просто используется мной;): EPFLx: scala-реактивныйX см. Лекция 2.5 Тестирование систем актеров :

  def fakeGetter(url:String, depth: Int):Props =
    Props(new Getter(url, depth){
      override def webClient: WebClient = FakeWebClient
    })
0 голосов
/ 18 февраля 2019

Если вы нуждаетесь в для насмешки, то все это можно сделать путём вычеркнутой черты.Если издеваться не нужно, избегайте этого.Насмешка излишне ... ненужна.Вы просто напрасно потратите время и силы на то, что не имеет никакой дополнительной ценности.

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

Хороший пример того, когда макет необходим, - это когда вы имитируете вызовы базы данных в приложении MVC (например, ScalaИграй микросервис).Очевидно, что вам не нужно запускать реальную базу данных при тестировании вашего кода, поэтому вы обычно макетируете слой коннектора и возвращаете фиктивные / поддельные данные из ваших функций коннектора.

Пример чего-то, что выне будет издеваться над чем-то вроде:

trait MyTrait {
  def toInt(str: String): Int
}

val mockedTrait = mock[MyTrait]
when(mockedTrait.toInt(eq("3")).thenReturn(3)

Это немного глупый пример, но я думаю, что это ясно объясняет суть - делать что-то подобное было бы смешно.Насмешка не всегда ответ.

...