8

I am trying to write a JUnit for below code but I am not getting any idea how to cover the code which is written in catch block statement. Please can any one write a sample JUnit for below code.

Here I don't want to cover any exception, but want to cover the lines of code written in the catch block using Mockito.

public Product getProductLookUpData() {

        Product product = null;
        try{
            // Try to get value from cacheable method
            product = productCacheDao.getProductLookUpData();
            .....//statements
        } catch (Exception ex) {
            // getting value from db
            product = productDao.getIpacMetricCodeLookUpData();
            ....//statements
        }

        return product;
    }
John
  • 258
  • 1
  • 5
  • 21
  • 1
    If you want to cover the code in the `catch` block, your test needs to cause an exception to be thrown in the `try` block. – khelwood Feb 28 '17 at 12:06
  • You will have to setup your test such that it will throw an exception. – Abubakkar Feb 28 '17 at 12:06
  • I think this can help you [unit Test Exception](http://stackoverflow.com/questions/156503/how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests) – code4fun Feb 28 '17 at 12:08
  • Yes i have tried that, but code is not entering into getProductLookUpData() catch block it is directly throwing exception and getting assertion failed. – John Feb 28 '17 at 12:09
  • @java4fun I am not expecting any exception, i wan't to cover the code in the catch block i.e i want to write the JUnit for the catch block. – John Feb 28 '17 at 12:11
  • 2
    Possible duplicate of [How to cover block catch by JUnit with NoSuchAlgorithmException and KeyStoreException](http://stackoverflow.com/questions/26359882/how-to-cover-block-catch-by-junit-with-nosuchalgorithmexception-and-keystoreexce) – Tom Feb 28 '17 at 12:36

3 Answers3

13

You can mock both productCacheDao and productDao and check how many times those methods were invoked in your test cases. And you can simulate exception throwing with those mock objects, like this:

when(mockObject.method(any())).thenThrow(new IllegalStateException());

So, for your case I would do something like this:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import static org.mockito.Mockito.*;

public class ProductTest {
    private static final Product CACHED_PRODUCT = new Product("some parameters for cached product");
    private static final Product DB_PRODUCT = new Product("some parameters for DB product");

    private ProductService service;
    private ProductDao productDaoMock;
    private ProductCacheDao productCacheDaoMock;

    @Before
    public void setup() {
        service = new ProductService();
        productDaoMock = mock(ProdoctDao.class);
        service.setProductDao(productDaoMock);

        productCacheDaoMock = mock(ProdoctCacheDao.class);
        service.setProductCacheDao(productCacheDaoMock);
    }

    @Test
    public void testCache() {
        when(productCacheDaoMock.getProductLookUpData(any())).thenReturn(CACHED_PRODUCT);

        final Product product = service.getProductLookUpData();

        Assert.assertEquals(CACHED_PRODUCT, product);
        verify(productCacheDaoMock, times(1)).getProductLookUpData(any());
        verify(productDaoMock, never()).getIpacMetricCodeLookUpData(any());
    }

    @Test
    public void testDB() {
        when(productCacheDaoMock.getProductLookUpData(any())).thenThrow(new IllegalStateException());
        when(productDaoMock.getIpacMetricCodeLookUpData(any())).thenReturn(DB_PRODUCT);

        final Product product = service.getProductLookUpData();

        Assert.assertEquals(DB_PRODUCT, product);
        verify(productCacheDaoMock, times(1)).getProductLookUpData(any());
        verify(productDaoMock, times(1)).getIpacMetricCodeLookUpData(any());
    }
}
esin88
  • 3,091
  • 30
  • 35
  • If i mock and expect the exception as the you gave the link will it cover the code of the catch block. – John Feb 28 '17 at 12:14
  • You can mock both those ojects: `productCacheDao` and `productDao`. Then, you should have 2 test cases: one for using `productCacheDao` and one for `productCacheDao` throwing exception and using `productDao`. In those cases you can check, how many times your methods were invoked with `verify` method. Watch this question for example: http://stackoverflow.com/questions/27787487/java-verify-void-method-calls-n-times-with-mockito – esin88 Feb 28 '17 at 12:17
  • @Pavan added mockito example. In the first case you check that your cache method was invoked once, and your DB method was never invoked. In the second case your cache method throws exception, and you check that your DB method was invoked once. – esin88 Feb 28 '17 at 12:28
4

Mockito, or another mocking framework can be used. You will need two test cases - with and without the exception being thrown. You can mock your DAOs to return a known object so you verify your service is exhibiting the correct behaviour.

I've written a full example below.

public class MocksExample {

    private ProductService service;
    @Mock
    private ProductDao productDao;
    @Mock
    private ProductCacheDao productCacheDao;
    @Mock
    private Product product;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        service = new ProductService();
        service.setProductCacheDao(productCacheDao);
        service.setProductDao(productDao);
    }

    @Test
    public void serviceReturnsProduct() {
        when(productCacheDao.getProductLookUpData()).thenReturn(product);
        assertThat(service.getProductLookUpData(), is(product));
    }

    @Test
    public void ipacProductReturnedWhenDaoThrowsException() {
        when(productDao.getIpacMetricCodeLookUpData()).thenReturn(product);
        when(productCacheDao.getProductLookUpData()).thenThrow(new IllegalStateException("foo"));
        assertThat(service.getProductLookUpData(), is(product));
    }
}
Adam
  • 35,919
  • 9
  • 100
  • 137
2

You can use Mocking frameworks like Mockito

In your JUnit Test you can do something like

public class YourTest {

  private ProductcacheDao productCacheDaoMock;

  @Before
  public void setup() throws Exception {

    productCacheDaoMock = Mockito.mock(ProductcacheDao.class);

  }

  @org.junit.Test
  public void test() {
      // Given
      Mockito.when(productCacheDaoMock.getProductLookUpData()).thenThrow(new RuntimeException());

      // When
      // do your stuff
      productCacheDaoMock.getProductLookUpData();

      // Then
      // ...
  }

}
thopaw
  • 3,796
  • 2
  • 17
  • 24