Mockito 匹配器、scala 值类和 NullPointerException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27289757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mockito matchers, scala value class and NullPointerException
提问by Marek Kli?
I'm using mockito with scalatest. I have following problem when using matcher with value class.
我正在使用带有 scalatest 的 mockito。使用具有值类的匹配器时出现以下问题。
import org.scalatest.FlatSpec
import org.scalatest.mock.MockitoSugar
import org.mockito.BDDMockito._
import org.mockito.Matchers.any
case class FirstId(val value: String) extends AnyVal
case class SecondId(val value: String) extends AnyVal
trait MockedClass {
def someMethods(firstId: FirstId, secondId: SecondId): Int
}
class ValueClassSpec() extends FlatSpec with MockitoSugar {
val mockedClass = mock[MockedClass]
val secondId = SecondId("secondId")
"Matchers" should "work for value class" in {
// given
given(mockedClass.someMethods(any[FirstId], org.mockito.Matchers.eq(secondId))).willReturn(3)
// when
val result = mockedClass.someMethods(FirstId("firstId"), secondId)
// then
assert(result == 3)
}
}
and the result is:
结果是:
ValueClassSpec:
Matchers
- should work for value class *** FAILED ***
java.lang.NullPointerException:
at io.scalac.fow.party.ValueClassSpec$$anonfun.apply$mcV$sp(ValueClassSpec.scala:22)
at io.scalac.fow.party.ValueClassSpec$$anonfun.apply(ValueClassSpec.scala:20)
at io.scalac.fow.party.ValueClassSpec$$anonfun.apply(ValueClassSpec.scala:20)
at org.scalatest.Transformer$$anonfun$apply.apply(Transformer.scala:22)
at org.scalatest.Transformer$$anonfun$apply.apply(Transformer.scala:22)
at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.FlatSpecLike$$anon.apply(FlatSpecLike.scala:1639)
...
I found similar question (Scala Value classes and Mockito Matchers don't play together) but without any advice.
我发现了类似的问题(Scala Value classes 和 Mockito Matchers don't play together)但没有任何建议。
Is there any posibility to use mockito matchers with scala value class?
是否有可能使用带有 Scala 值类的模拟匹配器?
Lib versions: scala 2.11.2, mockito 1.10.8, scalatest 2.1.6
Lib 版本:scala 2.11.2、mockito 1.10.8、scalatest 2.1.6
回答by Marek Kli?
The proper solution is:
正确的解决方法是:
case class StringValue(val text: String) extends AnyVal
case class LongValue(val value: Long) extends AnyVal
val eqFirst: StringValue = StringValue(org.mockito.Matchers.eq("first"))
val anySecond: StringValue = StringValue(org.mockito.Matchers.any[String])
val eqFirst: LongValue = LongValue(org.mockito.Matchers.eq(1L))
val anySecond: LongValue = LongValue(org.mockito.Matchers.any[Long])
回答by Marek Kli?
I found solution:
我找到了解决方案:
val anyFirstId: FirstId = any[String].asInstanceOf[FirstId]
val eqSecondId: SecondId = org.mockito.Matchers.eq[String](secondId.value).asInstanceOf[SecondId]
given(mockedClass.someMethods(anyFirstId, eqSecondId)).willReturn(3)
回答by mr MR
This works for all kinds of extends AnyValvalue classes and doesn't need special matchers either:
这适用于所有类型的extends AnyVal值类,也不需要特殊的匹配器:
given(mockedClass.someMethods(FirstId(anyString), SecondId(org.mockito.Matchers.eq(secondId.value)))).willReturn(3)
回答by Bruno
The newest version of mockito-scala(0.0.9) supports this out of the box, you can do something like
mockito-scala(0.0.9)的最新版本支持开箱即用,您可以执行以下操作
when(myObj.myMethod(anyVal[MyValueClass]) thenReturn "something"
myObj.myMethod(MyValueClass(456)) shouldBe "something"
verify(myObj).myMethod(eqToVal[MyValueClass](456))
Disclaimer: I'm a developer of that library
免责声明:我是该库的开发人员
回答by mark_dj
If you have shapeless in your dependencies you could consider my little helper method: https://gist.github.com/Fristi/bbc9d0e04557278f8d19976188a0b733
如果您的依赖项中没有shapeless,您可以考虑我的小助手方法:https: //gist.github.com/Fristi/bbc9d0e04557278f8d19976188a0b733
Instead of writing
而不是写作
UserId(is(context.userId.value))
UserId(is(context.userId.value))
You can write
你可以写
isAnyVal(context.userId)
isAnyVal(context.userId)
Which is a bit more convenient :-)
哪个更方便:-)

