Как смоделировать отправку http-клиента в тесте Scala? - PullRequest
5 голосов
/ 26 декабря 2011

У меня есть некоторый код, работающий с HTTP-запросами, и я хочу протестировать его.Таким образом я пытаюсь смоделировать dispatch.Http или даже лучше dispatch.HttpExecutor (0.8.5) с Scala (2.9.1.final), Mockito (1.9.0-rc1) и ScalaTest (1.6.1), но даже не могу сделать мой тестовый код компилируемым.Здесь, в MyHttpTest, я хочу получить определенный HTTP-ответ на любой HTTP-запрос:

import org.scalatest.FunSuite
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito.when
import org.mockito.Matchers.any
import dispatch._

class MyHttpTest extends FunSuite with MockitoSugar {
  test("example") {
    val httpMock = mock[HttpExecutor]
    when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_HTTP_response")
  }
}

Но он выдает ошибку компиляции:

error: overloaded method value thenReturn with alternatives:
(httpMock.HttpPackage[String],<repeated...>[httpMock.HttpPackage[String]])org.mockito.stubbing.OngoingStubbing[httpMock.HttpPackage[String]] <and>
(httpMock.HttpPackage[String])org.mockito.stubbing.OngoingStubbing[httpMock.HttpPackage[String]]
cannot be applied to (java.lang.String)
when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_response")

Так как же посмеяться над клиентом отправки?

Ответы [ 2 ]

6 голосов
/ 26 декабря 2011

Я собирался ответить на это с предложением, чтобы вы попробовали ScalaMock вместо Mockito, потому что я ошибочно предположил, что ваша проблема была вызвана тем, что Mockito не совсем понимал Scala (тогда как ScalaMock был создан в Scala с нуля). Тем не менее:

  1. Это не твоя проблема, а
  2. Оказывается, что ScalaMock терпит неудачу при попытке имитации HttpExecutor, потому что он не знает, как обрабатывать тип, определенный в объекте пакета (ExceptionListener). Черт! Я исправлю это как можно скорее - спасибо, что обратили на это мое внимание.

В любом случае, вы не можете создать экземпляр HttpExecutor#HttpPackage, потому что это абстрактный тип. Таким образом, чтобы обойти это, вам нужно расширить HttpExecutor и сделать HttpPackage бетон. Например:

class MyHttpTest extends FunSuite with MockitoSugar {
  trait TestHttpExecutor extends HttpExecutor {
    type HttpPackage[T] = T
  }
  test("example") {
    val httpMock = mock[TestHttpExecutor]
    when(httpMock.apply(any(classOf[Handler[String]]))).thenReturn("Some_HTTP_response")
  }
}
1 голос
/ 26 декабря 2011

Я ничего не знаю о Скале.Но, как правило, вы не должны пытаться высмеивать класс, который вам не принадлежит;и мне кажется, что приведенный выше HttpExecutor является одним из таких классов.

Шаблон, который действительно хорошо работает для тестируемости, заключается в разработке класса, который действует как оболочка для таких классов, но не имеет собственной функциональности.Затем напишите (как минимум) два отдельных тестовых класса -

  • интеграционный тестовый класс для вашего класса-оболочки, чтобы убедиться, что вы правильно вызываете HttpExecutor;
  • классы модульных тестов для любых классов, использующих ваш класс-обертку.

Класс интеграционных тестов вообще не должен иметь насмешек.У модульных тестов будет макет для вашего класса-оболочки.

Если я неправильно понял ваш вопрос - а HttpExecutor действительно ваш собственный класс - тогда опубликуйте снова, и я постараюсь дать другой ответ.

...