使用ScalaJ-Http时如何进行单元测试?

Nel*_*son 5 unit-testing scala

我希望使用ScalaJ-Http作为http客户端.链接:https://github.com/scalaj/scalaj-http

我将如何模拟HttpHttpRequest在单元测试中使用这样的代码行进行类val response: HttpResponse[String] = Http("http://foo.com/search").param("q","monkeys").asString

该类将从方法调用参数中获取url和params.所以我不能注射HttpRequest.

Rva*_*est 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!"
}
Run Code Online (Sandbox Code Playgroud)

2017 年 3 月 2 日编辑: 经过更多考虑,我更改了代码,以便在“facade”特征中通过 scalaj-http 进行 HTTP 调用,这样我就可以在测试中进行模拟。现在,我不再执行实际的 HTTP 请求,而是模拟外观并发送回预期的HTTPResponse. 与上面显示的解决方案相比,这更加干净,不再需要上面提到的依赖项,并且设置更容易。外观可以作为构造函数参数或自类型注释“注入”到执行 HTTP 调用的类中。