2016-12-12 4 views
3

Я пытаюсь реорганизовать некоторый код, который использует неявный класс. В принципе, это код для некоторых модульных тестов, в которых я делаю некоторые издевательства и шпионаже с Mockito.Scala неявные классы и функции

В приведенном ниже примере издевательство над этими функциями выполняется в неявном классе А. Каждый метод «overrideX» принимает ожидаемый результат, переопределяет вызов метода X в myObj и возвращает myObj (шаблон построения для простого объединения нескольких переопределяет позже).

object Outer { 
    "call to abc" should { 
    "fail if call to X fails" in { 
     val failReason = "X failed" 
     val myObjMock = B 

     myObjMock.overrideX(failReason) 
     myObjMock.abc mustEqual failReason 
    } 

    "fail if call to Y fails" in { 
     val failReason = "Y failed" 
     val myObjMock = B 

     myObjMock.overrideY(failReason) 
     myObjMock.abc mustEqual failReason 
    } 
    } 

    implicit class A(myObj: B) { 
    def overrideX(result: Result): B = { 
     //override call to X in myObj with result 
     myObj 
    } 

    def overrideY(result: Result): B = { 
     //override call to Y in myObj with result 
     myObj 
    } 
    } 
}  

Проблема, которую я пытаюсь решить, заключается в устранении большого количества плиты котла в испытаниях. Как вы можете видеть в приведенном выше примере, эти два теста выглядят очень похожими. То, что я хотел бы достичь, - создать некоторый метод, общий для обоих методов, которые будут использовать метод переопределения и выполнить фактическую проверку.

def somethingElse(result: Result, f: Result => B) = { 
    val myObjMock = B 
    myObjMock.f(result).abc mustEqual result 
} 

Тесты будут выглядеть как

"call to abc" should { 
    "fail if call to X fails" in { 
     val failReason = "X failed" 
     somethingElse(failReason, overrideX) 
    } 

    "fail if call to Y fails" in { 
     val failReason = "Y failed" 
     somethingElse(failReason, overrideY) 
    } 
    } 

Я знаю, что методы overrideX и overrideY находятся на классе, а не на объект компаньона.

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

ответ

2

Я думаю, что вам нужна функция (B, Result) => B вместо Result => B. Если у вас есть переменная f, которая содержит функцию, вы не можете называть ее на объекте, например myObjMock.f(...). Но вы можете пройти myObjMock в f, например f(myObjMock, ...).

def somethingElse(result: Result, f: (B, Result) => B) = { 
    val myObjMock = B 
    f(myObjMock, result).abc mustEqual result 
} 

"call to abc" should { 
    "fail if call to X fails" in { 
    val failReason = "X failed" 
    somethingElse(failReason, _.overrideX(_)) 
    } 

    "fail if call to Y fails" in { 
    val failReason = "Y failed" 
    somethingElse(failReason, _.overrideY(_)) 
    } 
} 
+0

спасибо. Работает как шарм. До сих пор не знал о _.methodCall (_). –

Смежные вопросы