Модульное тестирование вспомогательных или неинтерфейсных признаков в Scala
этот вопрос касается тестирования классов, которые смешиваются в неинтерфейсных чертах, то есть чертах, содержащих некоторую функциональность. При тестировании функциональность класса должна быть изолирована от функциональности, обеспечиваемой характеристикой mix-in (которая предположительно тестируется отдельно).
у меня простой Crawler
класс, который зависит от HttpConnection и HttpHelpers
набор служебных функций. Давайте теперь сосредоточимся на HttpHelpers.
In Java, HttpHelpers, возможно, будет служебным классом и передаст свой синглтон искателю в качестве зависимости либо вручную, либо с помощью некоторой структуры IoC. Тестирование Crawler является простым, так как зависимость легко издеваться.
В Scala кажется помощник черта является более предпочтительным способом составления функциональности. Действительно, его проще использовать (методы, автоматически импортируемые в пространство имен при расширении, могут использовать withResponse ...
вместо из httpHelper.withResponse ...
, etc.). Но как это влияет на тестирование?
это мое решение, которое я придумал, но, к сожалению, оно поднимает некоторую шаблонную панель на сторону тестирования.
помощник черта:
trait HttpHelpers {
val httpClient: HttpClient
protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...
protected def makeGetRequest(url: String): HttpResponse = // ...
}
код для проверки:
class Crawler(val httpClient: HttpClient) extends HttpHelpers {
// ...
}
2 ответов
вы можете написать вспомогательный макет, который должен быть смешан с HttpHelpers
и переопределить его методы с помощью макетного эквивалента:
trait HttpHelpersMock { this: HttpHelpers =>
//MOCK IMPLEMENTATION
override protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...
//MOCK IMPLEMENTATION
override protected def makeGetRequest(url: String): HttpResponse = // ...
}
затем, при тестировании crawler, вы смешиваете макет признака при создании экземпляра:
val crawlerTestee = new Crawler(x) with HttpHelpersMock
и макетные методы просто заменят вспомогательные методы в instance crawlerTestee
.
Edit: Я не думаю, что это хорошая идея, чтобы проверить, как класс взаимодействует с вспомогательной чертой. На мой взгляд, вы должны проверить Crawler
поведение, а не его внутренняя реализация. Реализации могут меняться, но поведение должно оставаться максимально стабильным. Процесс, описанный выше, позволяет переопределить вспомогательные методы, чтобы сделать их детерминированными и избежать реальной сети, тем самым помогая и ускоряя тесты.
тем не менее, я считаю, что имеет смысл проверить самого помощника, так как он может быть повторно использован в другом месте и имеет надлежащее поведение.
Как насчет:
val helpers = new HttpHelpers {
//override or define stuff the trait needs to work properly here
}
helpers.someMethodToTest
Смотри, Ма, без промежуточных черты и насмешливый библиотеки нужны!
Я делаю это все время для моих черт, и я был очень доволен результатом.