Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use mockito for testing a REST service?

I am very new in Java Unit Testing and I heard that Mockito framework is really good for testing purposes.

I have developed a REST Server (CRUD methods) and now I want to test it, but I don't know how?

Even more I don't know how this testing procedure should begin. My server should work on localhost and then make calls on that url(e.g. localhost:8888)?

Here is what I tried so far, but I'm pretty sure that this isn't the right way.

    @Test     public void testInitialize() {         RESTfulGeneric rest = mock(RESTfulGeneric.class);          ResponseBuilder builder = Response.status(Response.Status.OK);          builder = Response.status(Response.Status.OK).entity(                 "Your schema was succesfully created!");          when(rest.initialize(DatabaseSchema)).thenReturn(builder.build());          String result = rest.initialize(DatabaseSchema).getEntity().toString();          System.out.println("Here: " + result);          assertEquals("Your schema was succesfully created!", result);      } 

Here is the code for initialize method.

    @POST     @Produces(MediaType.APPLICATION_JSON)     @Path("/initialize")     public Response initialize(String DatabaseSchema) {          /** Set the LogLevel to Info, severe, warning and info will be written */         LOGGER.setLevel(Level.INFO);          ResponseBuilder builder = Response.status(Response.Status.OK);          LOGGER.info("POST/initialize - Initialize the " + user.getUserEmail()                 + " namespace with a database schema.");          /** Get a handle on the datastore itself */         DatastoreService datastore = DatastoreServiceFactory                 .getDatastoreService();           datastore.put(dbSchema);          builder = Response.status(Response.Status.OK).entity(                 "Your schema was succesfully created!");         /** Send response */         return builder.build();     } 

In this test case I want to send a Json string to the server(POST). If everything went well then the server should reply with "Your schema was succesfully created!".

Can someone please help me?

like image 342
Ion Morozan Avatar asked May 27 '12 15:05

Ion Morozan


People also ask

Is Mockito used for unit testing?

Mockito is a mocking framework, JAVA-based library that is used for effective unit testing of JAVA applications.

Can we use Mockito without JUnit?

Mockito Maven Dependencies Note that mockito-junit-jupiter is required for JUnit 5, if you are using any other testing framework such as JUnit 4 or TestNG then you remove this dependency and include only mockito-core dependency.


2 Answers

OK. So, the contract of the method is the following: Parse the input string as JSON, and send back BAD_REQUEST if it's invalid. If it's valid, create an entity in the datastore with various properties (you know them), and send back OK.

And you need to verify that this contract is fulfilled by the method.

Where does Mockito help here? Well, if you test this method without Mockito, you need a real DataStoreService, and you need to verify that the entity has been created correctly in this real DataStoreService. This is where your test is not a unit test anymore, and this is also where it's too complex to test, too long, and too hard to run because it needs a complex environment.

Mockito can help by mocking the dependency on the DataStoreService: you can create a mock of DataStoreService, and verify that this mock is indeed called with the appropriate entity argument when you call your initialize() method in your test.

To do that, you need to be able to inject the DataStoreService into your object under test. It can be as easy as refactoring your object in the following way:

public class MyRestService {     private DataStoreService dataStoreService;      // constructor used on the server     public MyRestService() {         this.dataStoreService = DatastoreServiceFactory.getDatastoreService();     }      // constructor used by the unit tests     public MyRestService(DataStoreService dataStoreService) {         this.dataStoreService = dataStoreService;     }      public Response initialize(String DatabaseSchema) {          ...          // use this.dataStoreService instead of datastore     } } 

And now in your test method, you can do:

@Test public void testInitializeWithGoodInput() {     DataStoreService mockDataStoreService = mock(DataStoreService.class);     MyRestService service = new MyRestService(mockDataStoreService);     String goodInput = "...";     Response response = service.initialize(goodInput);     assertEquals(Response.Status.OK, response.getStatus());      ArgumentCaptor<Entity> argument = ArgumentCaptor.forClass(Entity.class);     verify(mock).put(argument.capture());     assertEquals("the correct kind", argument.getValue().getKind());     // ... other assertions } 
like image 136
JB Nizet Avatar answered Sep 23 '22 18:09

JB Nizet


What you're talking about sounds more like integration testing and Mockito (or any other mocking frameworks) will not be of much use to you.

If you want to unit test code you've written, Mockito is certainly a useful tool.

I suggest you read more about mocking/unit testing and which circumstances it should be used in.

like image 44
darrengorman Avatar answered Sep 20 '22 18:09

darrengorman