Все мы знаем, что модульные тесты являются одной из наиболее важных частей приложения. Нет? Затем я должен сказать вам, что модульное тестирование является одним из самых ранних тестов, выполняемых на модуле кода, и чем раньше обнаруживаются дефекты, тем легче их исправить. Это уменьшает трудности обнаружения ошибок, содержащихся в более сложных частях приложения.
Итак, где же насмешка? Зачем нам это нужно? И как мы понимаем, что мы должны издеваться при написании модульных тестов? Ответы на эти вопросы прямо ниже в этом блоге.
Вам также может понравиться:
Руководство по издевательству с Мокито
Взгляд на издевательство
Есть программы, которые не имеют каких-либо зависимостей от внешних классов. Рассмотрим программу, в которой есть метод, который печатает «Hello, World». Теперь эта программа не зависит от каких-либо внешних классов. Однако в реальных приложениях классы имеют зависимости. Этими зависимостями могут быть некоторые службы, и эти службы могут зависеть от некоторых объектов базы данных, и этот список можно продолжить. Основная задача написания модульных тестовых примеров — проверить, работает ли наш фрагмент кода без взаимодействия с внешней средой, то есть, если был вызван какой-либо метод другого класса, то этот метод должен быть проверен.
Рассмотрим этот пример:
Scala
xxxxxxxxxx
1
class UserAction(loginService: LoginService) {
2
def displayActionsPerformed(val userId: String) {
3
val result = loginService.getListOfActionsPerformed(userId)
4
if(result.size > 0){
5
return SUCCESS
6
}
7
else {
8
return FAILURE
9
}
10
}
11
}
Из кода видно, что класс UserAction
зависит от LoginService
. Здесь, если мы начнем писать тестовые примеры для этого класса, мы начнем с тестирования displayActionPerformed
метода. Для этого мы должны быть в состоянии написать тестовые сценарии для этого метода без тестирования getListOfActionsPerformed
. Надо полагать, что getListOfActionsPerformed
проверено, чтобы работать так, как задумано. Вопрос в том, как мы тестируем displayActionsPerformed
без выполнения getListOfActionsPerformed
?
Это когда насмешка входит в картину. Идея насмешки заключается в том, что мы создадим фиктивный объект, чтобы он мог заменить реальный объект и действовать так же, как реальный объект. Макет объекта ожидает вызова определенных методов, и когда это произойдет, он вернет некоторый ожидаемый результат.
В этом примере у нас были проблемы с написанием тестовых случаев, потому что мы не хотели их выполнять getListOfActionsPerformed
. Итак, теперь с помощью насмешек мы можем издеваться над LoginService
классом и создавать имитируемый объект.
Этот фиктивный объект вызовет getListOfActionsPerformed
метод с параметром userId и вернет, скажем, список действий. Теперь мы можем легко протестировать displayActionsPerformed
метод, так как имеем результат его зависимостей.
Пример Mocking в Scala с использованием Mockito
Теперь, когда вы все поняли концепцию насмешек, давайте рассмотрим библиотеку Mockito в ScalaTest
.
ScalaTest MockitoSugar предоставляет базовый синтаксический сахар для Mockito. Есть еще варианты, которые мы можем использовать для насмешек, например, ScalaMock, EasyMock и JMock. В этом блоге мы будем обсуждать инфраструктуру Mockito.
Во-первых, нам нужно добавить эти две зависимости библиотеки в наш файл build.sbt:
Джава
xxxxxxxxxx
1
libraryDependencies ++= Seq ( "org.scalatest" %% "scalatest" % "3.0.1" % "test", "org.mockito" % "mockito-core" % "2.8.47" % "test" )
Теперь, рассматривая наш предыдущий пример, давайте напишем тестовые примеры для него, используя Mockito.
Scala
xxxxxxxxxx
1
Class UserActionSpec extends WordSpec with Matchers with MockitoSugar {
2
val mockedLoginService = mock[LoginService]
3
val userAction = new UserAction(mockedLoginService)
4
“UserAction#displalyActionsPerformed” should {
6
“ return SUCCESS” in {
8
when(mockedLoginService.getListOfActionsPerformed(any[String])) thenReturn List(“user logged in”, “user updated profile”)
9
val result = userAction.displayActionsPerformed(randomUserId)
10
result shouldBe SUCCESS
11
}
12
}
13
}
Вот:
- Мы высмеяли наш
LoginService
класс, от которого зависит UserAction. - При создании объекта для класса UserAction мы передали параметр mocked.
- Мы видим, как легко мы можем заглушить методы, используя функции Mockito:
when
иthenReturn
- Mockito также позволяет нам сопоставлять любое значение аргумента (как видно из приведенного выше примера, как мы использовали
any[String]
в качестве сопоставителя для параметра userId:.when(mockedLoginService.getListOfActionsPerformed(any[String]))
Он также поставляется с сопоставителями regex и позволяет писать собственные сопоставления. - Чтобы генерировать исключения с помощью Mockito, нам просто нужно использовать
thenThrow(….)
функцию. Вот как это можно сделать,
Scala
xxxxxxxxxx
1
Class UserActionSpec extends WordSpec with Matchers with MockitoSugar {
2
val mockedLoginService = mock[LoginService]
3
val userAction = new UserAction(mockedLoginService)
4
“UserAction#dispalyActionsPerformed” should {
6
“ return error” in {
8
when(mockedLoginService.getListOfActionsPerformed(any[String])) thenThrow(
9
new RuntimeException())
10
intercept[RuntimeException]{userAction.displayActionsPerformed(randomUserId)
11
}
12
}
13
}
14
}
Это было все о насмешках. Для получения дополнительной информации о платформе Mockito вы можете прочитать об этом в Руководстве пользователя Mockito .
Эта статья была впервые опубликована в блоге Knoldus .