如何使用 play framework FakeApplication() 进行多项测试?

How to use play framework FakeApplication() for multiple tests?

我想使用 FakeApplication 来测试 WS 调用,目前我有这样的:

class ExampleServiceSpec extends WordSpec with BeforeAndAfter {

private val client = new GenericGrafanaService

"Service" should {
    "post some json" in {
        Play.start(fakeApp)
        assertResult("OK") {
            Await.result(client.postSomeJson("key1", "string2"), Duration.Inf)
        }
        Play.stop(fakeApp)
    }

    "delete some json" in {
        Play.start(fakeApp)
        assertResult("OK") {
            Await.result(client.deleteSomeJson("key1"), Duration.Inf)
        }
        Play.stop(fakeApp)
    }
}
}

并且第一个测试通过了,但是对于下一个测试,我得到了这样的异常:

[info]   java.io.IOException: Closed
[info]   at com.ning.http.client.providers.netty.request.NettyRequestSender.sendRequest(NettyRequestSender.java:96)
[info]   at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.execute(NettyAsyncHttpProvider.java:87)
[info]   at com.ning.http.client.AsyncHttpClient.executeRequest(AsyncHttpClient.java:506)
[info]   at play.api.libs.ws.ning.NingWSClient.executeRequest(NingWS.scala:47)
[info]   at play.api.libs.ws.ning.NingWSRequest.execute(NingWS.scala:306)
[info]   at play.api.libs.ws.ning.NingWSRequest.execute(NingWS.scala:128)
[info]   at play.api.libs.ws.WSRequest$class.delete(WS.scala:500)
[info]   at play.api.libs.ws.ning.NingWSRequest.delete(NingWS.scala:81)
[info]   at de.zalando.steerage.abdiff.grafana.interface.ExampleService$$anonfun$deleteSomeJson.apply(ExampleService.scala:58)
[info]   at de.zalando.steerage.abdiff.grafana.interface.ExampleService$$anonfun$deleteSomeJson.apply(ExampleService.scala:56)
[info]   ...

即使更改测试顺序,我也会遇到同样的异常。我还尝试重复第一个测试两次(同一个调用),但第二个测试再次失败。我还尝试使用 before{}after{} 启动和停止 fakeApp,但我得到了相同的结果。我正在使用 play 2.4.

有人知道我可以如何调整我的代码吗?

设法使用 beforeAllafterAll 解决了这个问题。

class TestSpec extends WordSpec with BeforeAndAfterAll { 

    override def beforeAll {
        Play.start(fakeApp)
    }

    ...

    override def afterAll {
        Play.stop(fakeApp)
    }

}

来自https://www.playframework.com/documentation/2.4.x/ScalaFunctionalTestingWithScalaTest

Sometimes you want to test with the real HTTP stack. If all tests in your test class can reuse the same server instance, you can mix in OneServerPerSuite (which will also provide a new FakeApplication for the suite)

例如:

class ExampleServiceSpec extends WordSpec with BeforeAndAfter {

  private val client = new GenericGrafanaService

  "Service" should {
     "post some json" in {
        assertResult("OK") {
         Await.result(client.postSomeJson("key1", "string2"), Duration.Inf)
       }
     }

     "delete some json" in {
       assertResult("OK") {
         Await.result(client.deleteSomeJson("key1"), Duration.Inf)
       }
     }
  }
}