Scala Mock частичная заглушка
Я хотел бы заглушить один из методов класса Scala с зависимостями. Есть ли способ добиться этого с помощью ScalaMock?
Вот упрощенный пример того, что у меня есть:
class TeamService(val dep1: D1) {
def method1(param: Int) = param * dep1.magicNumber()
def method2(param: Int) = {
method1(param) * 2
}
}
В этом примере я хотел бы высмеять method1()
, Мой тест будет выглядеть так:
val teamService = ??? // creates a stub
(teamService.method1 _).when(33).returns(22)
teamService.method2(33).should be(44)
Есть ли способ добиться этого?
3 ответа
Как было предложено в других вопросах, здесь и здесь мы можем комбинировать
stub
с финалом. Из ScalaMock FAQ:
Могу ли я издеваться над финальными / частными методами или классами?
Это не поддерживается, поскольку макросы, созданные с помощью макросов, реализованы как подклассы того типа, который нужно макать. Таким образом, частные и окончательные методы не могут быть переопределены
Итак, вы можете объявить
method2
в исходном коде как окончательный, а затем проверьте:
it should "test" in {
val teamService = stub[TeamService]
(teamService.method1 _).when(33).returns(22)
teamService.method2(33) shouldBe 44
}
Или создайте новый класс переопределения, который объявляет ваш метод окончательным:
it should "test" in {
class PartFinalTeamService(dep: D1) extends TeamService(dep) {
override final def method2(param: Int): Int = super.method2(param)
}
val teamService = stub[PartFinalTeamService]
(teamService.method1 _).when(33).returns(22)
teamService.method2(33) shouldBe 44
}
Вы должны издеваться dep1: D1
так что все будет хорошо работать. Это не хороший подход, чтобы издеваться над "половиной" или только некоторыми методами.
Дразнящий dep1: D1
это правильный способ проверить это.
val mockD1 = mock[D1]
val teamService = new TeamService(mockD1)
(mockD1.magicNumber _).returns(22)
teamService.method2(33).should be(44)
Вы можете переопределить
method1()
при создании
TeamService
объект и заставить его возвращать любое значение, которое вы хотите.
val service = new TeamService(2) {
override def method1(param: Int): Int = theValueYouWant
}
И используйте
service
объект для проверки вашего
method2()
.