Scala 隐式 类 和函数
Scala implicit classes and functions
我正在尝试重构一些使用隐式 class 的代码。
基本上,它是一些单元测试的代码,我在其中使用 Mockito 进行了一些模拟和监视。
在下面的示例中,这些函数的模拟是在隐式 class A 中完成的。每个方法 "overrideX" 都采用预期结果,覆盖对 myObj 和 [= 中的方法 X 的调用30=] 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 方法在 class 而不是伴随对象上。
我目前有一个版本,其中 overrideXX 方法位于伴随对象中,并将结果和验证器作为参数。但它们不是隐含的,我不得不放弃构建器模式,所以不要链接它们。
我认为你需要的是函数 (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(_))
}
}
我正在尝试重构一些使用隐式 class 的代码。 基本上,它是一些单元测试的代码,我在其中使用 Mockito 进行了一些模拟和监视。
在下面的示例中,这些函数的模拟是在隐式 class A 中完成的。每个方法 "overrideX" 都采用预期结果,覆盖对 myObj 和 [= 中的方法 X 的调用30=] 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 方法在 class 而不是伴随对象上。
我目前有一个版本,其中 overrideXX 方法位于伴随对象中,并将结果和验证器作为参数。但它们不是隐含的,我不得不放弃构建器模式,所以不要链接它们。
我认为你需要的是函数 (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(_))
}
}