如何模拟scala泛型方法

如何模拟scala泛型方法,scala,mockito,Scala,Mockito,我有一个特性(下面是简单的版本),我想模拟Foo trait MyTrait[A] trait Foo { def bar[T: MyTrait](id:Int, data: T, other:Option[String] = None): String } 我试过: implicit val myTrait = new MyTrait[String] {} val src = mock[Foo] when(src.bar(any(),any(),any())).thenReturn(

我有一个特性(下面是简单的版本),我想模拟
Foo

trait MyTrait[A]

trait Foo {
  def bar[T: MyTrait](id:Int, data: T, other:Option[String] = None): String
}
我试过:

implicit val myTrait = new MyTrait[String] {}

val src = mock[Foo]
when(src.bar(any(),any(),any())).thenReturn("ok")

src.bar(1, "some", None)
它失败于:

参数匹配器的使用无效!预计4名匹配者,3名记录


如何模拟这种方法?

Mockito不能很好地使用scala代码。你的情况是
notify.bar(any(),any(),any())
必须在
when()
内部调用,但bar方法的类型未知,因此,当scalac隐式查找时,可能有多个
写入的实例适合于此(因为它们都可以)。
您可以这样做使其工作:

when(src.bar[T](any(),any(),any())).thenReturn("ok")
编辑

在编辑之后,我认为您首先应该重新考虑mockito的用法。下面是发生的情况: 脱胶后,Foo有以下签名

trait Foo {
 def bar[T](id:Int, data: T, other:Option[String] = None)(implicit ev: MyTrait[T]): String
}
我不知道您是否知道mockito是如何工作的,但这里有一个快速的解释(从我所知道的)为什么会发生这个错误:

  • 在运行时,方法栏具有以下“签名”(由于类型擦除):
    bar(id:Int,data:Object,other:Option[Object],ev:MyTrait[Object])
  • when(src.bar[T](any(),any(),any())。thenReturn(“ok”)
    实际上在代理对象上调用此方法并注册“matchers”,但ev是传递的
    myTrait
    而不是匹配器,因此我猜这违反了库的某些约束

旁注:通常mocking并没有那么难,您可以简单地实现一个“mocked”特性,而无需mockito或其他类似库的任何帮助

Mockito不能很好地处理scala代码。你的情况是
notify.bar(any(),any(),any())
必须在
when()
内部调用,但bar方法的类型未知,因此,当scalac隐式查找时,可能有多个
写入的实例适合于此(因为它们都可以)。
您可以这样做使其工作:

when(src.bar[T](any(),any(),any())).thenReturn("ok")
编辑

在编辑之后,我认为您首先应该重新考虑mockito的用法。下面是发生的情况: 脱胶后,Foo有以下签名

trait Foo {
 def bar[T](id:Int, data: T, other:Option[String] = None)(implicit ev: MyTrait[T]): String
}
我不知道您是否知道mockito是如何工作的,但这里有一个快速的解释(从我所知道的)为什么会发生这个错误:

  • 在运行时,方法栏具有以下“签名”(由于类型擦除):
    bar(id:Int,data:Object,other:Option[Object],ev:MyTrait[Object])
  • when(src.bar[T](any(),any(),any())。thenReturn(“ok”)
    实际上在代理对象上调用此方法并注册“matchers”,但ev是传递的
    myTrait
    而不是匹配器,因此我猜这违反了库的某些约束

旁注:通常mocking并没有那么难,您可以简单地实现一个“mocked”特性,而无需mockito或其他类似库的任何帮助

语法
[T:MyTrait]
很容易添加
(隐式类型类:MyTrait[T])
作为第二组参数,因此在错误状态下基本上缺少参数匹配器

所以如果你这样做了

val src = mock[Foo]
when(src.bar(any(),any(),any())(any())).thenReturn("ok")
它按预期工作


顺便说一句,这有点自我提升,但我刚刚发布了一个名为
mockito scala
的库,它改进了scala的mockito语法,是mockito生态系统的一部分,因此希望在使用scala时成为默认值,您可以在这里找到它,其中包含获取依赖关系的信息以及它实际上解决了哪些问题。

语法
[T:MyTrait]
非常适合添加
(隐式类型类:MyTrait[T])
作为第二组参数,因此基本上,在错误状态下,您缺少了一个参数匹配器

所以如果你这样做了

val src = mock[Foo]
when(src.bar(any(),any(),any())(any())).thenReturn("ok")
它按预期工作


顺便说一句,这有点自我提升,但我刚刚发布了一个名为
mockito scala
的库,它改进了scala的mockito语法,是mockito生态系统的一部分,因此希望在使用scala时成为默认值,您可以在这里找到它,其中包含获取依赖关系的信息以及它实际解决了哪些问题。

代码需要具体的类型,而不是T。仍然不知道如何使其工作我不知道您正在使用的特定类型,因此离开
T
,用您需要的任何东西替换它。代码需要具体类型,而不是
T
。仍然不知道如何使其工作我不知道您使用的具体类型,因此离开
T
,用您需要的任何东西替换它。