Showing posts with label Integration tests. Show all posts
Showing posts with label Integration tests. Show all posts

Saturday, February 27, 2016

JSON Assert lib released

I'm really happy to present the JSON Assert library - over-the-weekend project that came out from the AccuREST library. This post will describe the rationale behind creating this tool and how to use it.


Wednesday, October 24, 2012

Mockito InvocationOnMock - checking an argument



Hi!

In one of my projects we had a very interesting situation in terms of testing. We couldn't mock an invocation of a static method due to the fact that PowerMock was not allowed to be used so there were plenty of objects and dependencies being initialized. What is more we were using a custom made dependency injection system that had a possibility of injecting a mock.

The problem was such that during a test we wanted to assert whether one of the objects was in a very precise state. This object was created using the new operator so we couldn't mock it (again no PowerMock allowed). Fortunately this object got passed to a method of an object that we could mock...

As presented below timeConsumingExternalService is an object that we could mock via the custom dependency injection system whereas the SomePojo class is an object whose state we would like to verify.

timeConsumingExternalService.processSomeObject(new SomePojo("name", "surname", 1, 1.0));

So what we did was that in our mock to which the object got passed we created a new Answer (the same Answer that I spoke of here). Due to which we could access the InvocationOnMock and the arguments passed to the method as such.

Mockito.doAnswer(new Answer<Object>() {
   public Object answer(InvocationOnMock invocation) throws Throwable {
    Object[] object = invocation.getArguments();

      if (object.length > 0) {
          SomePojo somePojo = (SomePojo) object[0];

          Assert.assertEquals("name", somePojo.getName());
          LOGGER.debug("Names are equal");
          Assert.assertEquals("surname", somePojo.getSurname());
          LOGGER.debug("Surnames are equal");
          Assert.assertTrue(1 == somePojo.getIntValue());
          LOGGER.debug("Ints are equal");
          Assert.assertTrue(1.0 == somePojo.getDoubleValue());
          LOGGER.debug("Doubles are equal");

          LOGGER.debug("Object being an argument of the function [" + String.valueOf(somePojo) + "]");
  }
    return null;
   }
  }).when(timeConsumingExternalServiceMock).processSomeObject(Mockito.any(SomePojo.class));

Of course the logs regarding the equalities are unnecessary since if they wouldn't be equal we would have an assertion exception - I left them for the purpose of this post.

And in the logs we can find:

pl.grzejszczak.marcin.ServiceIntegrationTest:48 Names are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:50 Surnames are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:52 Ints are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:54 Doubles are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:56 Object being an argument of the function [SomePojo [name=name, surname=surname, intValue=1, doubleValue=1.0]]

So in this way something that seems impossible to be verified can get verified :)

Update!

Thanks to Holger's suggestion I took a look at the ArgumentCaptor object and that is true that it is an elegant solution to retrieve information about the arguments executed on a method. Where InvocationOnMock can give you much more information and possibilities (for instance regarding the method being executed or just execute the real method) for this particular case a much more elegant, easier and faster way of dealing with the issue would be:


  //service that executes the external service
  executorService.execute(someTask);

  final ArgumentCaptor<SomePojo> argumentCaptor = ArgumentCaptor.forClass(SomePojo.class);
  Mockito.verify(timeConsumingExternalServiceMock).processSomeObject(argumentCaptor.capture());
  SomePojo somePojo = argumentCaptor.getValue();
  Assert.assertEquals("name", somePojo.getName());
  LOGGER.debug("Names are equal");
  Assert.assertEquals("surname", somePojo.getSurname());
  LOGGER.debug("Surnames are equal");
  Assert.assertTrue(1 == somePojo.getIntValue());
  LOGGER.debug("Ints are equal");
  Assert.assertTrue(1.0 == somePojo.getDoubleValue());
  LOGGER.debug("Doubles are equal");

The logs:
pl.grzejszczak.marcin.junit.SomeTask:26 Before processing an object
pl.grzejszczak.marcin.junit.SomeTask:28 After processing an object
pl.grzejszczak.marcin.ServiceIntegrationTest:75 Names are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:77 Surnames are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:79 Ints are equal
pl.grzejszczak.marcin.ServiceIntegrationTest:81 Doubles are equal

Thanks again Holger!

Sunday, October 7, 2012

Simulation of time consuming actions in integration tests



Hi!

Quite recently in one of my projects I had a situation in which I needed to create an integration test for the application. That's not very odd isn't it? :)

What was interesting was the fact that the logic of the app involved some concurrency issues and one of the components had to connect to an external service which would take a couple of seconds. Since in the integration test there was no need to make the actual connection, the component needed to be mocked. What about the simulation of the time consuming action? Well, let's take a look at the way I did it...

The task.

package pl.grzejszczak.marcin;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Service that does some things including processing of the external service
 * 
 * @author marcin
 * 
 */
public class SomeTask implements Runnable {

 private static final Logger LOGGER = LoggerFactory.getLogger(SomeTask.class);

 // Service is injected via a dependency injection system
 private Processable timeConsumingExternalService;

 private void methodThatConnectsToExternalServices() {
  // connects to an external service and spends a couple of seconds there
  LOGGER.debug("Before processing");
  timeConsumingExternalService.process();
  LOGGER.debug("After processing");
  // some other things to do
 }

 public void run() {
  methodThatConnectsToExternalServices();
 }

 public void setTimeConsumingExternalService(Processable timeConsumingExternalService) {
  this.timeConsumingExternalService = timeConsumingExternalService;
 }

}
The integration test.

package pl.grzejszczak.marcin;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServiceIntegrationTest {

 private static final Logger LOGGER = LoggerFactory.getLogger(ServiceIntegrationTest.class);

 private ExecutorService executorService = Executors.newCachedThreadPool();
 private Processable timeConsumingExternalServiceMock = Mockito.mock(Processable.class);
 private SomeTask someTask = new SomeTask();

 public ServiceIntegrationTest() {
  initializeMocks();
 }

 private void initializeMocks() {
  Mockito.doAnswer(new Answer<Object>() {
   public Object answer(InvocationOnMock invocation) throws Throwable {
    // Simulation of connection to external services
    LOGGER.debug("Sleeping");
    Thread.sleep(5000);
    LOGGER.debug("Stopped Sleeping");
    return null;
   }
  }).when(timeConsumingExternalServiceMock).process();
  // Inject the mock to the Task - in any possible way
  someTask.setTimeConsumingExternalService(timeConsumingExternalServiceMock);
 }

 public void executeTest() {
  executorService.execute(someTask);
 }

 public static void main(String args[]) {
  ServiceIntegrationTest integrationTest = new ServiceIntegrationTest();
  integrationTest.executeTest();
 }
}


And the output to the console:

2012-10-07 22:42:37,378 DEBUG pl.grzejszczak.marcin.SomeTask:21 Before processing
2012-10-07 22:42:37,389 DEBUG pl.grzejszczak.marcin.ServiceIntegrationTest:28 Sleeping
2012-10-07 22:42:42,390 DEBUG pl.grzejszczak.marcin.ServiceIntegrationTest:30 Stopped Sleeping
2012-10-07 22:42:42,392 DEBUG pl.grzejszczak.marcin.SomeTask:23 After processing

Let's take a closer look at the most important part in which an Answer for the execution of the service is being created
Mockito.doAnswer(new Answer<Object>() {
   public Object answer(InvocationOnMock invocation) throws Throwable {
    // Simulation of connection to external services
    LOGGER.debug("Sleeping");
    Thread.sleep(5000);
    LOGGER.debug("Stopped Sleeping");
    return null;
   }
  }).when(timeConsumingExternalServiceMock).process();

This piece of code changes the default action that should be done by the given object on a given method execution. In this particular case we had to mock a method that returns void - that's why we start with doAnswer(...) and finish with when(...).process().

That is how inside the integration test I managed to create a simulation of waiting for the service to finish. If you have any ideas or comments on how you would do it in another way please feel free to post a comment below :)