简体   繁体   中英

Best way to test a REST service in java

  1. What is the best way to test REST services in Java? What approaches and tool set do developers usually take?

  2. Also if you are writing rest clients that call into third party REST services. What is the best way to test REST clients. Do you have JUnit tests that communicate with a third party REST service. You could run into the risk of service not being available/or production REST service cannot be access without certain credentials.

1. What is the best way to test REST services in Java? What approaches and tool set do developers usually take?

  • You can test your rest services by first testing the actual code and functionality of the service itself and make sure it is functioning properly using any unit testing library applicable to your project. Next, you would publish the REST service and try accessing the RESTful methods using a http client of some sort.
    Generally, the easiest way is just a plain old browser. Type in the url and information if it is a GET or PUT based request. If it is a post, you can use browser plugins or dev tools to help add data to the body of the request or header as needed and validate you are getting the response you expect. If it works in a browser, it should perform similarly with any HTTP capable client you choose.

2. Also if you are writing rest clients that call into third party REST services. What is the best way to test REST clients. Do you have JUnit tests that communicate with a third party REST service. You could run into the risk of service not being available/or production REST service cannot be access without certain credentials.

  • You can generally use any sort of Http Client library you wish based on the language you are using. The main pitfall to look out for with testing of a REST client is to make sure you are capturing the Response returned by the REST service and checking the status. If it is good, you will get a 200, server error 500, etc. etc.
    I recommend taking a look at W3C or Wikipedia status code information https://en.wikipedia.org/wiki/List_of_HTTP_status_codes or https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html .
    Further, you should understand the types of responses that are possible to be returned from the particular service. This should be available in the api documentation for the service. The api should also explain any sort of credentials or requirements that need to be passed through the header or as a parameter to the REST call.

Understanding how REST works and HTTP in general would be good starting points.

There are several ways to test REST API, depends on your needs:

  • Jersey Test - you can execute and test REST API calls with in-memory HTTP server. You'll need to mock your code - use Mockito ( Jersey 1.19 Test configuration - mock classes ) or in-memory testing database.
  • Rest Assured - the main drawback is that you need to run REST API project separately/individually from tests ( RestAssured testing without running Tomcat )
  • Tools with UI - SOAP UI or Postman
  • Swagger - generates interactive documentation - web page where you execute REST methods with prepared data according annotated methods in a code.
  • Use Spring Boot for developing REST services. It has various tools for testing which you can use out of the box without excessive configuration.

You can create a REST Service mock using SoapUI . Also, if you needed to run this test through maven, you can use soapui-maven-plugin to instanciate do soapui service automatically

I suggest that you take a look at REST Assured for automated testing of REST services. The following example is copied from it's web page :

For example if your HTTP server returns the following JSON at “ http://localhost:8080/lotto/ {id}”:

{
   "lotto":{
      "lottoId":5,
      "winning-numbers":[2,45,34,23,7,5,3],
      "winners":[
         {
            "winnerId":23,
            "numbers":[2,45,34,23,3,5]
         },
         {
            "winnerId":54,
            "numbers":[52,3,12,11,18,22]
         }
      ]
   }
}

You can easily use REST Assured to validate interesting things from response:

@Test public void
lotto_resource_returns_200_with_expected_id_and_winners() {

    when().
            get("/lotto/{id}", 5).
    then().
            statusCode(200).
            body("lotto.lottoId", equalTo(5), 
                 "lotto.winners.winnerId", containsOnly(23, 54));

}

See the getting started and usage guides for more information.


If you have implemented your server app using Spring Boot, you may also find the blog post about Integrating Testing a Spring Boot Application that I wrote a couple of years ago interesting. It shows how Spring Boot test support starts an embedded web server and deploys the application to it before executing REST Assured based tests against the REST API. In other words, neither do you have to manually start a web server, nor do you need to re-deploy the app between tests. As a matter of fact, you do not even have to create a .war or .jar file between your code changes in order to validate REST API changes.

For part 2 in your question, the correct answer depends on various factors. You would want to consider both the resolution of the mocking and the time spent writing and maintaining the tests.

Client library

The choice of HTTP-client will affect your options - some klients (like Spring RestTemplate) offer built-in mocking support. If you have a service definition like a swagger or RAML file, you'd want to generate the client.

Project configuration

The most thorough way is to actually let the application make HTTP calls to real endpoints, involving the full stack. If so, configure your project so that the client URLs are injected in a per-environment (or profile) fashion.

Mock endpoints

You want mocking per unit test. No 'deployable mocks' which serve multiple unit-tests. Services are mocked on a localhost port - preferably randomly selected so that parallell testing is possible (ie on jenkins).

Mock data

To save time, for deep data structures, it is very desirable that mock data is read from a file, rather than constructed programmatically. Files are much easier to work with, especially if you enable request/response logging, fixing bugs and so is faster.

Mocking

Some frameworks are loosely coupled to the service, as in they are strictly not aware of the nature of the service. Typically you'd mock a respons at some path which is coded in the unit test. This is like Wiremock and most of the test frameworks I've seen.

Whereas other tools work directly on class service definitions, basically you'd use a tool like Mockito to mock an object directly (but wrapped in a real endpoint). This should be less error prone, but requires the classes to be present (as test dependencies). I've written a tool like that, for comparison.

Karate is a framework that has been designed from the ground up for testing web-service API-s. It has its own tag on Stack Overflow.

There is a detailed comparison with REST-assured here . It has also been listed as one of the top 5 open-source API testing tools, just within 6 months of its release.

Disclaimer: I happen to be the author of Karate.

Karate is a framework that has been designed from the ground up for testing web-service API-s. It has its own tag on Stack Overflow.

There is a detailed comparison with REST-assured here . It has also been listed as one of the top 5 open-source API testing tools, just within 6 months of its release.

Disclaimer: I happen to be the author of Karate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM