Introducing restfuse – a JUnit Extension to test REST APIs

Introducing restfuse – a JUnit Extension to test REST APIs

Editor’s note: This project is no longer maintained and has been archived. However, you can still access the sources on GitHub.

For several projects at EclipseSource we are creating REST APIs. I’m involved in most of them and there is one thing that bothers me with every project. That is, testing. I mean, of course we are writing our unit tests first and we mock our services to get fast unit tests, but at some point you also have to make sure that the whole system works with integration tests. And, when writing integration tests for REST APIs in Java, as far as I know, there are currently only two solutions.

The first one is to write plain JUnit tests and do all the requests yourself within the test methods (maybe with the help of utilities). The other option is to use a library called rest-assured. This library provides a kind of DSL for testing REST APIs. You can write your tests with JUnit and use mockito-like syntax to send a request and test the response. But this doesn’t feel like the right solution, because you always have to configure your request with real Java code within your test method. I would prefer a solution where I can simply configure the request using something like annotations and just execute the test after the request is sent.

Another thing that bugs me are asynchronous services. When it comes to handling asynchronous services you always have two options: callbacks or polling. How can I test those services? For polling it’s easier – you can loop the request code – but does this sound right to you? For callbacks you have to open a server, again within your test method or before. It seems there are no cool solutions for this right now – even rest-assured can’t handle these services very well. That’s why I took a little time and tried to solve these problems. The result is a small library called restfuse.

Restfuse is a JUnit extension. It introduces an annotation called @HttpTest which can be used to configure a request. The request is sent before the annotated method is executed as a test method. The response is then injected into the test object and can be used within the test method. It also provides some new asserts like assertNotFound or assertOk to test response codes. A simple @HttpTest looks like this:

@RunWith( HttpJUnitRunner.class )
public class RestfuseTest {

  @Rule
  public Destination destination = new Destination( "http://restfuse.com" ); 

  @Context
  private Response response; // will be injected after every request

  @HttpTest( method = Method.GET, path = "/" )
  public void checkRestfuseOnlineStatus() {
    assertOk( response );
  }  
}

And of course, it also solves the problem with asynchronous services by introducing two annotations called @Callback and @Poll which can be used together with the @HttpTest annotation. For more information on these tests for asynchronous services take a look at the restfuse site.

Restfuse is open source, licensed under the EPL v – 1.0 and is hosted at github. The 1.0 version is also in the Maven Central and online as a p2 repository (yes, it’s an OSGi bundle).  I hope this small library will help you as much as it helped me. I would appreciate feedback on how to make restfuse even better.

9 Comments
  • Posted at 11:06 am, November 14, 2011

    Another similar approach of declaring the REST endpoint is crest. http://crest.codegist.org/

    It is not a unit testing framework but rather a framework to consume REST services declaratively.

  • Bernhard Jakob
    Reply
    Posted at 2:22 pm, November 14, 2011

    I am not using HttpUnit, because there are too many functions missing. Now I am using the Wink client and write plain JUnit tests and do all the requests myself within the test methods.

  • Alexander Kiel
    Reply
    Posted at 1:00 am, November 16, 2011

    I think using @RunWith, @Rule and custom annotations is a good way to build a nice DSL inside JUnit. I use the MethodRules and custom annotations myself for various exception matching situations.

    But I ask myself, if it is sufficient to have only constant expressions as in an annotation to specify a HTTP request. I for example use the Jersey Client inside JUnit for may integration tests against a REST API. With the Jersey Client I can use JAXB to build my request entities. So I don’t have to use files as you support them. Having the request entities in external files, can harm readability the whole test case.

    It may be good to have a fluent interface to specify the request inside the test method.

    One other thing: Normally I have to set up a database fixture for my test case. As I setup the database fixture inside the test method, the request would issued to early.

    So there are many things consider. But I have about 1000 tests against a REST API of a application at work with database fixtures. So I’m interested in optimizing them.

  • Posted at 7:21 pm, November 29, 2011

    Hi Holger, I’m trying restfuse lib. This lib is really cool for testing REST API.

    currently, I want to make a POST http to rest api, but it not working, could you tell me how i set some field values like this one:

    @HttpTest(method = Method.POST, path = “/mongo/post.php”, content = “status=1” )
    public void testPost() {
    com.eclipsesource.restfuse.Assert.assertOk(response);
    int responseCode = response.getStatus();
    System.out.println(responseCode);
    System.out.println(response.getBody(String.class));
    }

    thanks !

  • Posted at 1:44 am, December 1, 2011

    Hi Trieu,

    I was having the same problem.
    You just need to specify the MediaType and Content parameters.
    For example:

    @HttpTest(
    method = Method.POST,
    path = “/cities”,
    content=”name=Washington&country=US”,
    type= MediaType.APPLICATION_FORM_URLENCODED)
    public void postCityShouldCreateNewCity() {
    assertCreated(response);
    }

  • julien
    Reply
    Posted at 3:02 pm, December 5, 2011

    can someone explain me how to use restfuse test during maven test phase before installation and deploiement?
    thanks

Post a Comment

Comment
Name
Email
Website