2017-01-31 4 views
3

Я ищу, чтобы использовать ScalaJ-Http как http-клиент. Ссылка: https://github.com/scalaj/scalaj-httpКак тестировать устройство при использовании ScalaJ-Http?

Как бы я издеваться Http или HttpRequest в модульном тесте для класса с строки кода, как этот val response: HttpResponse[String] = Http("http://foo.com/search").param("q","monkeys").asString?

Класс возьмет url и params из аргументов вызова метода. Поэтому я не могу ввести HttpRequest.

ответ

0

Любопытный, если у вас уже есть решение для этого. Я столкнулся с вашим сообщением тем же вопросом.

Я, наконец, решил это, просто создав «фиктивный сервис» в самом тесте, используя Scalatra/Jetty и указав ожидаемые ответы там. Значит, это не издевательство, но это будет для меня.

Даунсайд к этому подходу заключается в том, что в качестве дополнительных зависимостей вам необходимо включить Scalatra, Jetty-сервер и Jetty-сервлет (необязательно с областью = тест).

def mockService: Server = { 
    class MockedServlet extends ScalatraServlet { 

    get("/") { 
     // fill in whatever you expect here 
     Ok("I'm alive!") 
    } 
    } 

    class ServletMounter extends LifeCycle { 
    override def init(context: ServletContext): Unit = { 
     context.mount(new MockedServlet, "/mock") 
    } 
    } 

    new Server(20002) { 
    val servlet = new ServletContextHandler(ServletContextHandler.NO_SESSIONS) { 
     addEventListener(new ScalatraListener() { 
     override def probeForCycleClass(classLoader: ClassLoader): (String, LifeCycle) = { 
      (classOf[ServletMounter].getSimpleName, new ServletMounter) 
     } 
     }) 
    } 
    setHandler(servlet) 
    } 
} 

private val server = mockService 

override protected def beforeAll(): Unit = { 
    super.beforeAll() 
    server.start() 
} 

override protected def afterAll(): Unit = { 
    server.stop() 
    server.destroy() 
    super.afterAll() 
} 

// a simple test 
"service up" should "return a 200 when the mocked service is up" in { 
    val response = Http("http://localhost:20002/mock/").asString 
    response.code shouldBe 200 
    response.body shouldBe "I'm alive!" 
} 

Edit 2 марта 2017: После еще некоторых раздумий я изменил свой код таким образом, что у меня есть вызов HTTP через scalaj-клиента в «фасадной» черты, что я могу издеваться в моем тесты. Теперь, вместо того, чтобы выполнять фактический запрос HTTP, я высмеиваю фасад и отправляю ожидаемый HTTPResponse. По сравнению с решением, показанным выше, это намного чище, вышеупомянутые зависимости больше не нужны, и настройка проще. Фасад может быть «введен» в класс, который выполняет HTTP-вызов как либо параметр конструктора, либо как аннотацию самонастройки.

+0

Итак, ваш класс, содержащий клиентский клиент scala-j, попадает в макетный сервер? Это может сработать, но, конечно, если бы существовало решение для насмешек над клиентом, это было бы идеально. – Nelson

0

То, что я сделал, было создать класс-оболочку ScalajHttp так:

import scalaj.http.{Http, HttpRequest} 

/** 
    * This wraps the Scalaj Http object so it can be injected. 
    */ 
class ScalajHttp { 

    def url(url: String): HttpRequest = Http(url) 

} 

Тогда вы можете легко вводить его в другой класс:

class Foo(http: ScalajHttp) { 

    def doBar() = { 
    val response = http.url("http://...").asString 
    } 

} 

Тогда для насмешливый вы можете использовать что-то вроде Specs2 и создать макет ScalajHttp.