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:"で始まるテキストベースの接続を期待する。