我希望将ScalaJ-Http用作http客户端。链接:https://github.com/scalaj/scalaj-http
我如何在单元测试中模拟Http
或HttpRequest
一个具有一行代码的类val response: HttpResponse[String] = Http("http://foo.com/search").param("q","monkeys").asString
?
该类将从方法调用参数中获取url和params。所以我不能注入HttpRequest
。
答案 0 :(得分:1)
我所做的是创建一个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的模拟。
答案 1 :(得分:0)
好奇,如果你已经有了解决方案。我遇到了同样的问题。
我现在终于通过创建一个虚拟服务'来解决它。在测试中使用Scalatra / Jetty并在那里指定预期的响应。所以,它不是真的嘲笑,但它会为我做。
这种方法的缺点是你必须包括Scalatra,Jetty-server和Jetty-servlet作为额外的依赖项(可选择使用scope = test)。
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!"
}
编辑2017年3月2日:
经过一些考虑之后,我改变了我的代码,以便通过scalaj-http在' facade'中进行HTTP调用。特质,我可以在我的测试中嘲笑。现在,我不是做实际的HTTP请求,而是模拟外观并发回预期的HTTPResponse
。与上面显示的解决方案相比,这更加清晰,上面提到的依赖性不再是必需的,并且设置更容易。外立面可以注入'进入作为构造函数参数或自我类型注释进行HTTP调用的类。