我的项目中有一个服务类,我想测试一个执行api调用的方法,所以我想抓住这个调用并返回一些假的,这样我就可以测试我的方法了,它看起来像这样:
class MyService @Inject()(implicit config: Configuration, wsClient: WSClient) {
def methodToTest(list: List[String]): Future[Either[BadRequestResponse, Unit]] = {
wsClient.url(url).withHeaders(("Content-Type", "application/json")).post(write(list)).map { response =>
response.status match {
case Status.OK =>
Right(logger.debug("Everything is OK!"))
case Status.BAD_REQUEST =>
Left(parse(response.body).extract[BadRequestResponse])
case _ =>
val ex = new RuntimeException(s"Failed with status: ${response.status} body: ${response.body}")
logger.error(s"Service failed: ", ex)
throw ex
}
}
}
}
现在在我的测试课中我去了:
class MyServiceTest extends FreeSpec with ShouldMatchers with OneAppPerSuite with ScalaFutures with WsScalaTestClient {
implicit lazy val materializer: Materializer = app.materializer
lazy val config: Configuration = app.injector.instanceOf[Configuration]
lazy val myService = app.injector.instanceOf[MyService]
"My Service Tests" - {
"Should behave as im expecting" in {
Server.withRouter() {
case POST(p"/fake/api/in/conf") => Action { request =>
Results.Ok
}
} { implicit port =>
WsTestClient.withClient { implicit client =>
whenReady(myService.methodToTest(List("1","2","3"))) { res =>
res.isRight shouldBe true
}
}
}
}
}
}
我收到此错误:
scheme java.lang.NullPointerException: scheme
也尝试过在client =>下:
val myService = new MyService {
implicit val config: Configuration = configuration
implicit val ws: WSClient = client
}
但得到了一些其他错误,我在构造函数中没有足够的参数......
为什么不起作用?
如果有更好的更简单的方法来伪造这个api电话,我很乐意听到它:)
谢谢!
答案 0 :(得分:1)
Server.withRouter
可能不是您想要的。它创建一个服务器并将其绑定到每个实例的随机端口(除非您指定端口)。它还会创建自己的应用程序实例,该实例将与您用于实例化服务的应用程序断开连接。
另一件事是注入的WSClient
不相对于您的应用程序。您需要使用传递给client
块的WsTestClient.withClient
。所以,你应该这样做:
class MyServiceTest extends FreeSpec with ShouldMatchers with OneAppPerSuite with ScalaFutures with WsScalaTestClient {
implicit lazy val materializer: Materializer = app.materializer
lazy val config: Configuration = app.injector.instanceOf[Configuration]
"My Service Tests" - {
"Should behave as im expecting" in {
Server.withRouter() {
case POST(p"/fake/api/in/conf") => Action { request =>
Results.Ok
}
} { implicit port =>
WsTestClient.withClient { implicit client =>
// Use the client "instrumented" by Play. It will
// handle the relative aspect of the url.
val myService = new MyService(client, config)
whenReady(myService.methodToTest(List("1","2","3"))) { res =>
res.isRight shouldBe true
}
}
}
}
}
}