我正在尝试模拟具有不同数量参数的过载方法的Java通用接口。接口代码是:
import java.util.concurrent.Callable;
public interface GOInterface<T> {
void send(T record);
void send(T record, Callable<T> onComplete);
}
我尝试使用oncomplete功能模拟发送的发送:
导入java.util.concurrent.callable
import org.scalamock.scalatest.MockFactory
import org.scalatest.{FlatSpec, Matchers}
class JavaInterfaceTest extends FlatSpec with Matchers with MockFactory {
behavior of "scalamock"
it should "mock java generic interface with overloaded method (with different number of parameters)" in {
var result = ""
val m = mock[GOInterface[String]]
(m.send(_: String, _: Callable[String])).expects(*, *)
.onCall{ case(s: String, c: Callable[String]) => c.call()}.once
m.send("hello", new Callable[String] {
override def call(): String = {result = "world"; result}
})
result should be("world")
}
it should "mock java generic interface with overloaded method (with different number of parameters) 2" in {
var result = ""
val m = mock[GOInterface[String]]
(m.send(_: String)).expects(*).once
m.send("hello")
result should be("")
}
}
我从编译器遇到的错误是:
error: value expects is not a member of (String, java.util.concurrent.Callable[String]) => Unit
[ERROR] (m.send(_: String, _: Callable[String])).expects(*, *)
[ERROR] ^
error: value expects is not a member of String => Unit
[ERROR] (m.send(_: String)).expects(*).once
[ERROR]
查看Scalamock Git上的不同示例,我可以看到没有测试可以使用具有不同param计数的过载方法检查通用接口。
我的依赖性是:
<dependency>
<groupId>org.scalamock</groupId>
<artifactId>scalamock-scalatest-support_2.11</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scalamock</groupId>
<artifactId>scalamock-core_2.11</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>
我在Scalamock repo中创建了一个错误。
我设法克服了这个问题。不是最干净的方式,而是它的作品。正如@philippm所建议的那样,我需要修复类型,但不幸的是,这还不够,我需要创建一个虚拟类。这是对我有用的解决方案:
class JavaInterfaceTest extends FlatSpec with Matchers with MockFactory {
behavior of "scalamock"
class StringInterface extends GOInterface[String] {
override def send(record: String): Unit = ()
override def send(record: String, onComplete: Callable[String]): Unit = ()
}
val call: (String, Callable[String]) => Unit = { case(s: String, c: Callable[String]) => c.call()}
it should "mock java generic interface with overloaded method (with different number of parameters)" in {
var result = ""
val m = mock[StringInterface]
(m.send(_: String, _: Callable[String])).expects(*, *)
.onCall{ call }.once
m.send("hello", new Callable[String] {
override def call(): String = {result = "world"; result}
})
result should be("world")
}
it should "mock java generic interface with overloaded method (with different number of parameters) 2" in {
var result = ""
val m = mock[StringInterface]
(m.send(_: String)).expects(*).once
m.send("hello")
result should be("")
}
}
我觉得这有点丑陋,当需要嘲笑更复杂的界面时,它可能会最糟糕,但我希望它可以帮助他人。
首先,我建议升级到最新版本的scalamock,但是那里也可能存在仿制药和过载的角案例。
要解决这个问题,在许多情况下,它有助于先锁定类型,然后创建一个模拟:
trait StringGoInterface extends GoInterface[String]
val m = mock[StringGoInterface]