我定义了一个扩展函数类型的类:
class Action1 extends (String => String) {
def apply(s:String) = s + "!"
}
它可以用于其他方法:
class Action2(action1: Action1) extends (String => String) {
def apply(n:String) = {
val all = (action1 andThen toUpper)
all(n)
}
private def toUpper(s:String) = s.toUpperCase
}
我可以使用模拟编写Action2
的单元测试:
val action1 = mock[Action1]
action1.apply(anyString) returns "sss"
action2.andThen(any) returns ??? // I don't want to mock this
val action2 = new Action2(action1)
val result = action2("aa")
result must beEqual("SSS")
你可以看到我需要模拟apply
和andThen
,这有点无聊。
如果我可以使用函数来模拟action1
,那就太棒了,比如:
val action2 = new Action2(_ => "sss")
val result = action2("aa")
result must beEqual("SSS")
未编译,因为_ => "sss"
无法转换为Action1
。如果我将Action2
更改为:
class Action2(action1: String => String) extends (String => String)
它将被编译,但我将失去Action1
类型的提示。
如果有任何方法可以保持类型Action1
,还有像_ => "sss"
这样的简单函数来进行模拟吗?
答案 0 :(得分:0)
问题是Action1
是Function1的子类,因此以下内容无法编译:
val f: (String => String) = ...
val a: Action1 = f // Does not compile
除了真正的Action1
到Action2
之外,您还有两个选择:
apply
或Action1
Action2
。对于选项1,您可以使用Mockito' s spy feature:
val action1 = new Action1
val spy = Mockito.spy(action1)
Mockito.when(spy.apply(org.mockito.Matchers.anyString)).thenReturn("sss")
val action2 = new Action2(spy)
val result = action2("aa")
result must beEqual("SSS")
对于选项2,您可以接受String => String
:
class Action2(action1: String => String) extends (String => String) { ... }
可能有别名:
type Action = (String => String)
class Action1 extends Action {
def apply(s:String) = s + "!"
}
class Action2(action1: Action) extends Action {
def apply(n:String) = {
val all = (action1 andThen toUpper)
all(n)
}
private def toUpper(s:String) = s.toUpperCase
}
val action2 = new Action2((s: String) => "sss")
val result = action2("aa")
result must beEqual("SSS")
或引入特征:
trait Action extends (String => String)
class Action1 extends Action { ... same as above ... }
class Action2(action1: Action) extends Action { ... same as above ...}
def mockedAction1(r: String) = new Action { def apply(s:String) = r }
val action2 = new Action2(mockedAction1("sss"))
val result = action2("aa")
result must beEqual("SSS")