EclipseSource は、REST/HTTPサービスのテストを自動化するJUnit 拡張の最初の安定バージョンをオープンソースでリリースした。Restfuse はJUnitのアノテーションセットであり、個別の HttpJUnitRunner と一緒に、HTTPコールのレスポンスへのアサーションを提供する。同期と非同期の両方のリモートコールがサポートされている。
Restfuseは既に Maven Centralにあるので、それを使うのに特別なリポジトリは不要である。
<dependency> <groupId>com.restfuse</groupId> <artifactId>com.eclipsesource.restfuse</artifactId> <version>1.0.0</version> </dependency>
同期コール用のライブラリを使うのは、簡単である。
@RunWith( HttpJUnitRunner.class ) public class RestFuseTest { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; // will be injected after every request @HttpTest( method = Method.GET, path = "/reloadLocalConfiguration" ) public void checkRestfuseOnlineStatus() { assertOk( response ); String answerBody = response.getBody(String.class); assertEquals("Expected correct response","done",answerBody); } }
上記のテストは、HTTPエンドポイントを同期的に呼び、テキストベースのレスポンス(text/plain)を "done" 文字列でチェックする。注目すべきなのは、最初のassertOk は Restfuseアサートで HTTP 200 OKステータスをチェックするが、2番目の assertEquals は、 JUnitが提供している通常の文字列の等値アサートである。このエンドポイントは、平文を返すと仮定できるが、 JSON/XMLかなんかを簡単にパースして、構造化された方法でアサートを実行することもできる。
Restfuseはまた、非同期な呼び出しもサポートしている。典型的な例は、時間のかかる操作(例えば、ファイルのアップロード操作)である。クライアントは、絶えずサーバーのエンドポイントをポーリングして、実際のステータスに関するフィードバックを常に収集する。ある操作の進捗を表示するために、サーバーのエンドポイントは、0~100の数を返すとする。
@RunWith( HttpJUnitRunner.class ) public class PollTest1 { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; @Context private PollState pollState; @HttpTest( method = Method.GET, path = "/progressStatus" ) @Poll( times = 5, interval = 500 ) public void testAsynchronousService() { if(pollState.getTimes() == 5) { String answerBody = response.getBody(String.class); assertEquals("Expected last response","100",answerBody); } } }
上のテストは、同じエンドポイントを5回(特定の間隔で)呼び、最後のコールの時だけ、実際のHTTPレスポンスをチェックする。
PollState Interface の別の面白いフィーチャは、今までの全レスポンスの履歴を保持していることである。これによって、コールの履歴でアサートできる。
@RunWith( HttpJUnitRunner.class ) public class PollTest2 { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; @Context private PollState pollState; @HttpTest( method = Method.GET, path = "/progressStatus" ) @Poll( times = 5, interval = 500 ) public void testAsynchronousService() { int currentRun = pollState.getTimes(); if(currentRun > 1) { String previousProgress = pollState.getResponse(currentRun - 1).getBody(String.class); String presentProgress = response.getBody(String.class); assertTrue("Expected some progress",Integer.parseInt(presentProgress) > Integer.parseInt(presentProgress)); //Just for illustration purposes } } } }
上記のテストは、各レスポンスが前の値より大きな数かをチェックする。
Restfuseの最も驚かされる依存性の1つが、Jetty HTTP サーバーである。この理由は、 Restfuseも Web Hooks ガイドラインに従う非同期なサービスをサポートしているからである。サーバーを何度も呼ばずに、クライアントのエンドポイントは、一度だけ呼び、完全に別のコネクションで、サーバー側 から 起動されるレスポンスを 待つ 。
@RunWith( HttpJUnitRunner.class ) public class RestfuseCalbackTest { @Rule public Destination destination = new Destination( "http://example.com" ); @Context private Response response; private class TestCallbackResource extends DefaultCallbackResource { @Override public Response post( Request request ) { assertTrue("Expected a quote response", request.getBody(String.class).startsWith("quote:") ); return super.post( request ); } } @HttpTest( method = Method.GET, path = "/requestQuote" ) @Callback( port = 9090, path = "/asynchron", resource = TestCallbackResource.class, timeout = 10000 ) public void testMethod() { assertAccepted( response ); } }
上記の例は、一度 requestQuote
に接続し、 クライアントのポート9090をリスンする。10秒以内に、"quote:"で始まるテキストベースの接続を期待する。