Scalamock: как указать произвольную последовательность кортежей - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь создать макет для WSClient Play следующим образом:

  def mockGet[A](url : String, method : String, headers : Seq[(String, String)], timeout : Duration)(
    response: Future[AhcWSResponse]
  ) =
    (mockWsClient
      .url(_ : String)
        .withMethod(_ : String)
        .withHttpHeaders(_: (String, String)*)
        .withRequestTimeout(_ : Duration)
        .stream())
      .expects(url, method, headers, timeout)
      .returning(response)

Проблема в withHttpHeaders - на самом деле это занимает (String, String) *, но когда я указываю этот тип, как указано выше Я получаю ошибку компилятора, такую ​​как:

[error]  found   : Seq[(String, String)]
[error]  required: (String, String)
[error]       .withHttpHeaders(_: Seq[(String, String)])

Какой тип мне нужно указать для этого метода, потому что (String, String) не является правильным. Фактическое реальное определение этого метода:

  override def withHttpHeaders(headers: (String, String)*): Self

ОБНОВЛЕНИЕ

Я попробовал это после предложения @ Марио:

  def mockGet[A](url: String, method: String, headers: Seq[(String, String)], timeout: Duration)(
    response: (String, String, Duration) => Future[ws.WSResponse]
  ) =
    (
      (
        xs: Seq[(String, String)]
      ) =>
        mockWsClient
          .url(_: String)
          .withMethod(_: String)
          .withRequestTimeout(_: Duration)
          .withHttpHeaders(xs: _*)
          .stream()
      )
      .expects(headers)
      .returning(response)

но это приводит к сбою компилятора с:

[error] value x$1

1 Ответ

1 голос
/ 20 февраля 2020

Ключ должен понять, как работает синтаксис параметра анонимной функции . Например, если

def f(i: Int*) = ???

, то

f(_: Int)

расширяется до

(i: Int) => f(i)

Следовательно, попробуйте

def mockGet(headers : Seq[(String, String)) =
  ((xs: Seq[(String, String)]) => mockWsClient.withHttpHeaders(xs: _*)).expects(headers)

Вот упрощенный пример

trait Zar {
  def f(i: Int*) = i
}

class ScalamockVarargsSpec extends FlatSpec with Matchers with MockFactory {
  "Varargs" should "be mockable" in {
    val zar = mock[Zar]
    ((xs: Seq[Int]) => zar.f(xs: _*)).expects(Seq(1,2))
    zar.f(1,2)
  }
}

В вашем конкретном случае существует несколько параметров-заполнителей анонимных функций, поэтому попробуйте расширить их все, например

def mockGet(url: String, headers : Seq[(String, String)) =
  ((u: String, xs: Seq[(String, String)]) => mockWsClient.url(u).withHttpHeaders(xs: _*))
    .expects(url, headers)
...