Play服务器的目的是充当另一个系统的中间服务,最终用户可以在智能手机上的Web浏览器中访问一小部分功能。
当连接到真实系统时,服务应该起作用。但是,我希望以黑盒方式进行单元测试。从头到尾测试功能。为了避免依赖每天值变化的真实系统,我想使用Testing web service clients中描述的相同方法,并将其与路由测试相结合,如play-java-seed中的示例测试所示,为方便起见,这里显示:
public class HomeControllerTest extends WithApplication {
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder().build();
}
@Test
public void testIndex() {
Http.RequestBuilder request = new Http.RequestBuilder()
.method(GET)
.uri("/");
Result result = route(app, request);
assertEquals(OK, result.status());
}
}
我的测试代码如下所示:
package controllers;
import java.util.*;
import org.junit.*;
import static org.junit.Assert.*;
import play.Application;
import play.inject.guice.GuiceApplicationBuilder;
import play.mvc.Result;
import play.mvc.Http.RequestBuilder;
import play.routing.*;
import play.server.Server;
import play.test.WithApplication;
import static play.mvc.Http.Status.*;
import static play.mvc.Results.*;
import static play.test.Helpers.*;
public class ApplicationControllerTest extends WithApplication {
static int FAKE_SERVICE_PORT = 7070;
Server server;
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder()
.configure("externalSystem.port", FAKE_SERVICE_PORT)
.configure("externalSystem.host", "localhost")
.build();
}
@Before
public void setup() {
Router router = new RoutingDsl()
.GET("/b/1/").routeTo(() ->
// Request for branch information
ok().sendResource("externalSystem/getBranch.json")
)
.GET("/b/1/a/19033/").routeTo(() ->
// Request generating an already arrived appointment
ok().sendResource("externalSystem/arrivedAppointment.json")
)
.GET("/b/1/a/19962/").routeTo(() ->
// Request generating a newly created appointment
ok().sendResource("externalSystem/createdAppointment.json")
)
.build();
server = Server.forRouter(router, FAKE_SERVICE_PORT);
}
@After
public void tearDown() throws Exception {
server.stop();
}
@Test
public void AppCtrl() throws Exception {
// // These values are defined in the json files
String customerName = "Test User";
String branchName = "Test Branch";
RequestBuilder request = new RequestBuilder().method(GET).uri("/1/19962");
Result result = route(app, request);
assertEquals(OK, result.status());
assertTrue(contentAsString(result).contains(customerName));
assertTrue(contentAsString(result).contains(branchName));
}
}
但是,使用sbt test
运行此测试会产生IllegalStateException:
[error] Test controllers.ApplicationControllerTest.AppCtrl failed: java.lang.IllegalStateException: Attempted to call materialize() after the ActorMaterializer has been shut down., took 4.165 sec
[error] at akka.stream.impl.ActorMaterializerImpl.materialize(ActorMaterializerImpl.scala:164)
[error] at akka.stream.impl.ActorMaterializerImpl.materialize(ActorMaterializerImpl.scala:146)
[error] at akka.stream.scaladsl.RunnableGraph.run(Flow.scala:350)
[error] at play.api.libs.streams.DoneAccumulator.run(Accumulator.scala:161)
[error] at play.api.test.EssentialActionCaller$class.call(Helpers.scala:225)
[error] at play.api.test.Helpers$.call(Helpers.scala:382)
[error] at play.api.test.RouteInvokers$class.route(Helpers.scala:247)
[error] at play.api.test.Helpers$.route(Helpers.scala:382)
[error] at play.api.test.RouteInvokers$class.jRoute(Helpers.scala:234)
[error] at play.api.test.Helpers$.jRoute(Helpers.scala:382)
[error] at play.api.test.Helpers.jRoute(Helpers.scala)
[error] at play.test.Helpers.route(Helpers.java:360)
[error] at play.test.Helpers.route(Helpers.java:355)
[error] at controllers.ApplicationControllerTest.AppCtrl(ApplicationControllerTest.java:63)
[error] ...
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error] controllers.ApplicationControllerTest
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
我想我可以实现一个完全独立的服务器来模拟服务,但我宁愿不让测试依赖于单独的服务器。
所以我的问题是这样的:有没有人做过与Play类似的东西,在那种情况下我做错了什么?