【问题标题】:Mocking elastic4s client getting Type mismatch, How to mock elastic4s client模拟elastic4s客户端获取类型不匹配,如何模拟elastic4s客户端
【发布时间】:2019-05-18 18:05:58
【问题描述】:

我正在使用 elastic4s 作为我对 ElasticSearch 的访问层,并且我正在尝试在我的应用程序中编写一些单元测试。我使用 scalaMock 作为我的模拟库。我想模拟 elastic4s client.execute 函数,以便能够测试我的代码。

这是经过测试的代码:

def insert(elasticDbConnection: ElasticClient, entIndexName: String, entTypingName: String, autoId: String, newJsonEntVal: String): Option[List[String]] = {

    import com.sksamuel.elastic4s.http.ElasticDsl._
    val req: IndexRequest = indexInto(index = entIndexName, `type` = entTypingName)
        .id(id = autoId).source(newJsonEntVal).refreshImmediately

    val insertRequests: List[IndexRequest] = List(req)

    val execRes: Future[Response[BulkResponse]] = elasticDbConnection.execute(bulk(insertRequests))

    val insertRes: BulkResponse = execRes.await.result

    val insertedEnts = insertRes.successes.map(resItem => resItem.id).toList

    Some(insertedEnts)
}

现在单元测试代码是:

...
import com.sksamuel.elastic4s.http.ElasticDsl._

val execRes: Future[Response[BulkResponse]]= mock[Future[Response[BulkResponse]]]
val elasticClientMock = mock[ElasticClient]
(elasticClientMock.execute _).expects(_:BulkRequest).returns(execRes).once()

testElasticsDal.insert(elasticClientMock, "indexName", "entType", "test-id", "{testField:\"testValue\"}")

我收到一个错误:“类型不匹配,预期:FunctionAdapter1[BulkRequest, Boolean],实际:BulkRequest 类型不匹配,预期:MockParameter[BulkRequest],实际:BulkRequest"

我做错了什么?我应该如何测试我的应用程序代码?我应该如何模拟客户端?

谢谢

【问题讨论】:

  • 似乎execute 需要更多的参数,而不仅仅是您的 BulkRequest,因此您可能还需要处理这些参数。 def execute[T, U, F[_]](t: T)(implicit functor: Functor[F], executor: Executor[F], handler: Handler[T, U], manifest: Manifest[U]): F[Response[U]]
  • 谢谢Philipp,我知道执行签名,但是如何模拟函数呢?我所做的是将执行的函数包装在一个特征和扩展它的类中(特征 elasticHelper{ def insert(client:ElasticClient, requests: IndexRequest)})。我将隐含的 elasticHelper 参数添加到插入函数中,现在我可以模拟特征并将我的模拟实现隐式发送到插入函数。这是一种解决方法还是正确的模拟方式?
  • 我喜欢从难以模拟的 API 中抽象出来的外观,但看起来 elastic4s 已经有一些模式可以做到这一点,而且这些模式看起来非常通用。如果你能找到一个在测试上下文中评估调用的F[_],也许你甚至不需要在这里模拟。但我没有使用过这个库,所以我不确定它会是什么样子。

标签: unit-testing elasticsearch scalatest elastic4s scalamock


【解决方案1】:

这不是最令人愉悦的,但这应该可以帮助您入门。 重要的部分是说明所有隐式参数,并在定义预期调用时使其显式。我发明了虚拟类来展示一个最小的例子,而不是把它和实际的 elastic4s 东西混在一起。

class BulkResponse
class Response[T]
class ImplicitFoo
abstract class Foo {
  def ex2[T, U](t: T)(implicit foo: ImplicitFoo): Response[U]
}

"A test" can "mock implicit params" in {
  val foo = mock[Foo]
  (foo.ex2[BulkResponse, String](_: BulkResponse)(_: ImplicitFoo)).expects(*, *).returns(new Response[String]).once()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多