Exception Testing

Reading Time: 2 minutes

Introduction

The post will be briefly focusing on testing exceptions in Java. We will be looking at a traditional way of handling Exceptions in Junit as well as benefit from the AssertJ test library.

The case study

In this section we will see a small service that is responsible of throwing a custom checked exception only 🙂 then we will figure out how we can test the exception.

public class ProcessService {
    public void runSomeProcess(String processName) {
        String message = String.format("The process '%s' was interrupted because of unknown error", processName);
        throw new ProcessInterruptedException(message);
    }

    public static class ProcessInterruptedException extends RuntimeException {
        public ProcessInterruptedException(String message) {
            super(message);
        }
    }
}

Traditional way of testing

Generally speaking, whenever I had to test a method that resulted in an exceptional situation, I would always favored of a traditional method, assuming the expected exception would be thrown by the method and carried on.

@Test(expected = ProcessService.ProcessInterruptedException.class)
    public void shouldRunProcessAndCatchTheExceptionUsingJunit() {
        //given
        String processName = "NvidiaBackgroundScanner";

        //when - then
        processService.runSomeProcess(processName);
    }

The good old days, that just allowed me to define the expected exception in the annotation, accordingly the method invocation raises the exception.

What if we need to assert multiple things in the exception?

That’s a splendid question, isn’t it? What if we want to have a couple of checks, first and most important; the exception message. Then later the type of the exception. In this matter, the AssertJ test library comes to rescue! In the below code snippet, we will be fully covering our essential needs;

    @Test
    public void shouldRunProcessAndCatchTheExceptionUsingAssetJ() {
        //given
        String processName = "NvidiaBackgroundScanner";

        //when
        Throwable throwable = catchThrowable(() -> processService.runSomeProcess(processName));

        //then
        String expectedException = String.format("The process '%s' was interrupted because of unknown error", processName);
        assertThat(throwable).isNotNull();
        assertThat(throwable)
                .isInstanceOf(ProcessService.ProcessInterruptedException.class)
                .hasMessage(expectedException);
    }

As you can see, the AssetJ library catches the Exception and gives us ways to check the type of the Exception as well as the content! It is very simple and intuitive to test with AssertJ. That’s all folks. Last of all, here are the imports you need in the test

 import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;

Russian Roulette in Testing

Reading Time: 4 minutes

Description

Russian Roulette, the dangerous Russian game that we are all familiar with from usually movies. The Urban Dictionary gives such small description; “A game where a revolver with one bullet is placed and spun. Then you take turns putting the gun to your head and pull the trigger. If it’s empty, you pass it on until someone dies or becomes extremely injured.

By now we have filled our heads up with this literature, let’s narrow the subject down on how I relate this blog post to the Russian Roulette. Well, the good news is that I’ll not suggest to play it of course, but it is a good metaphor of a situation that I have experienced and the word came to my mind. Here follows the background; recently I was reviewing my Colleagues’ PRs and I noticed such code snippets in the IT test that they were getting objects from positional access in list data structures and assuming that the objects in the zero, first and second positions allegedly had expected values.

After I read those test cases a few times, the notion of the Russian Roulette popped up in my head. Eventually I came up with proper solutions towards the prevention of such messy assertions. I’ll describe two situations along with my suggested solutions. Please assume that demonstrations simple and non complex to outline more the cause.

Last of all, to demonstrate my samples, I am using the mirror servers of Fedora Linux Distribution @ https://mirrors.fedoraproject.org/mirrorlist?repo=epel-7&arch=x86_64

Situation: Asserting a Single value in a Collection

While coding a method that gathers or filters a list from the persistence unit, we tend to iterate through the list, grab and assume that the Nth element will be our expected value. In essence, it may lead to a very naive behavior, here is a code snippet

@Test
    public void shouldFindPolishHostFromSecureEuropeanHostsRussianRoulette() {
        //given
        final String expectedAddress = "https://ftp.icm.edu.pl/pub/Linux/fedora/linux/epel/7/x86_64/";

        //when
        final List<Host> hosts = repository.findByAddressContaining("http");

        //then
        assertThat(hosts).isNotNull();
        assertThat(hosts.get(2).getAddress()).isEqualTo(expectedAddress);
    }

As you observe the code and apprehend the logic quickly, we are getting a list of servers that are non-secure only http protocol. Here we have a catch which is, we are very very sure that the second element in the list will be the expected one. In fact it can be, however here can possible things may occur in the future:

  • If you update the memory database package or switch to another one, the new alternative may return the values in a different order because of its internal design. Thus, your test will obviously fail,
  • When the next developer adds a new entry before or after your test data, such tests will most likely fail.

Solution: Implement ways to look for the Exact Figure

The title of the solution reveals the whole deal right. Which one is more feasible way to ensure integrity, assumption or precision? Obviously precision is the keyword here. Here is the code snippet:

 @Test
    public void shouldFindPolishHostFromSecureEuropeanHostsNonRussianRoulette() {
        //given
        final String expectedAddress = "https://ftp.icm.edu.pl/pub/Linux/fedora/linux/epel/7/x86_64/";

        //when
        final Host host = repository.findByAddress(expectedAddress);

        //then
        assertThat(host).isNotNull();
        assertThat(host.getAddress()).isEqualTo(expectedAddress);
    }

My suggestion is when we are exactly looking for a single value, we must be in true certainty, and look for an exact figure like in the above example. Implement methods that will query for certain values or search the persistence unit.

Situation: Asserting a Collection of values with hard coded values

Throughout my software development career, I always came across with such situations in which I have a list of expected values that must be ensured the computer had produced same or similar output. This situation can come from different varieties and sorts. Instead of discussing possibilities at the table, let’s look at this code snippet and begin a rare case:

 @Test
    public void shouldFindAllSecureEuropeanHostsRussianRoulette() {
        //given-when
        final List<Host> hosts = repository.findByAddressContaining("https");

        //then
        assertThat(hosts).isNotNull();
        assertThat(hosts.get(0).getAddress()).isEqualTo("https://mirror.karneval.cz/pub/linux/fedora/epel/7/x86_64/");
        assertThat(hosts.get(1).getAddress()).isEqualTo("https://ftp.icm.edu.pl/pub/Linux/fedora/linux/epel/7/x86_64/");
        assertThat(hosts.get(2).getAddress()).isEqualTo("https://ftp-stud.hs-esslingen.de/pub/epel/7/x86_64/");
    }

In this example, we are hard core assuming that the given Nth element will have such outcome as we type in. In this case I have the same failure point of predictions as I declared in the above situation, nothing more to address here.

Solution: Compare Collections with Collections

As we get the spoiler from the title wouldn’t it be nice to purely compare collections with collections? I must say, I really admire the way that I approached this situation and the solution as well as the testing frameworks support into it. Let’s apprehend my solution here

@Test
    public void shouldFindAllSecureEuropeanHostsNonRussianRoulette() {
        //given
        ArrayList<String> expectedHosts = new ArrayList<>(Arrays.asList("https://mirror.karneval.cz/pub/linux/fedora/epel/7/x86_64/",
                "https://ftp.icm.edu.pl/pub/Linux/fedora/linux/epel/7/x86_64/",
                "https://ftp-stud.hs-esslingen.de/pub/epel/7/x86_64/"));
        //when
        final List<Host> hosts = repository.findByAddressContaining("https");

        //then
        final List<String> hostNames = hosts.stream().map(Host::getAddress).collect(Collectors.toList());
        assertThat(hosts).isNotNull();
        assertThat(hostNames).isNotNull();
        assertThat(hostNames).containsAnyElementsOf(expectedHosts);
    }

The code is very simple to understand its purpose, in this solution I really don’t need to know in which position I get what outcome. The importance here is to ensure the computer had prepared the output that has the desired output, it as simple as that. Furthermore, the testing framework provides such method that ensures the output meets the expectation

Bonus Solution: Extracted Properties of Collections

I asked my colleague at work for a favor of evaluation my work and I was really curious about his opinion and thoughts. He had pointed me some features from the AssertJ library that I find very useful and the feature Assertions on Iterables can be quite comprehensive as well. In basic terms I also added a new test to simply cover the concept up

@Test
    public void shouldFindAllSecureEuropeanHostsNonRussianRouletteNonStream() {
        //given
        ArrayList<String> expectedHosts = new ArrayList<>(Arrays.asList("https://mirror.karneval.cz/pub/linux/fedora/epel/7/x86_64/",
                "https://ftp.icm.edu.pl/pub/Linux/fedora/linux/epel/7/x86_64/",
                "https://ftp-stud.hs-esslingen.de/pub/epel/7/x86_64/"));
        //when
        final List<Host> hosts = repository.findByAddressContaining("https");

        //then
        assertThat(hosts).isNotNull();
        assertThat(hosts).extracting("address")
                .containsAnyElementsOf(expectedHosts);
    }

In my sample I only demonstrated the “extracting” that eliminated my stream operation. On the other hand I’d like to share some links that will demonstrate way more advanced test cases than my humble test.

Conclusion

Assumptions can be evil in programming. Unless you work on sorted data structures that will guarantee the order, still assuming the positional access can be malicious, my sincere suggestion is that we shall always strive for best practices to overcome such bad habits, thus we won’t waste time on fixing unnecessary test cases. You can find the full solution at my Github repository @ https://github.com/tugrulaslan/BlogCodeSnippets/tree/master/RussianRoulette

Featured Image Courtesy telegraph.co.uk – https://i.telegraph.co.uk/multimedia/archive/02500/Russian_roulette_2500016k.jpg

Mocking methods with return type void

Reading Time: < 1 minuteFor a long while I’ve been looking forward to mocking void methods, I always thought that would be fairly impossible. After a long search online I’ve found it how to do it. So this example is from my work, it is a simple dummy method which creates a user on a 3rd party system.

import static org.mockito.Mockito.doNothing;
@Autowired
@Mock
private BusinessObjectsService boService;

private static final String testUserName = "TESTTESTTEST";
private static final String testUserNameLastName = "TEST";
private static final String testUserEmail = "TEST@TEST.COM";

@Before
	public void setUp() throws Exception {
                MockitoAnnotations.initMocks(this);
		when(boService.checkUserExistence(testUserName)).thenReturn(true);
		
	}
@Test
	public void createUserTest() {
//The method is being mocked!
		doNothing().when(boService).createUser(testUserName, testUserNameLastName,
 testUserNameLastName, testUserEmail);
		boolean userExistence = boService.checkUserExistence(testUserName);
		assertEquals(true, userExistence);
	}

outcome; success the test passed!

 

JUnit exception testing

Reading Time: < 1 minuteNow a days while I discover TDD and testing in software development, I’ve come to realize that it is also possible to test exceptions in Junit as well. I’ve noticed this while I was checking a code snippet of a software online and right after that I’ve tested the same thing to see the outcome. Simply to demonstrate the way of it, I’ll write a sample code snipped for you to easily and carefully study.

The test will be conducted using Junit version 4 and preferred IDE is IntelliJ.

@Test(expected = IndexOutOfBoundsException.class)
    public void exceptionTestCase() {
        //Create a list with simple dummy data
        List<String> myList = Arrays.asList("A", "B", "C");

        assertNotNull("The corresponding object is not null",myList);

        assertEquals("The collection has three elements",3, myList.size());

        //Cause the collection to throw an IndexOutofBoundException
        myList.get(Byte.MAX_VALUE);

    }

Here in the @Test annotation we first of all write our expected exception which will be throw by the candidate method. As you see there is no assert method being implemented.On the other hand you’ll see that the code has successfully passed the test

Spring Junit DAO Test Transaction Rollback Issue

Reading Time: < 1 minuteFor a long while i have been having this crazy incident in Spring transaction which cause me headaches while conducting tests for backend development. The Issue i face is that I’ve dozen of test methods which test different functionality of my Database methods, firstly creation methods are being conducted and I do carry out other editing deletion test, but I need data for it.

So after the data is created next steps failed because in spring test transaction is whether successfully ended up or not it is rolled back, so after I’ve checked it ended up with the real solution. First of all you can directly set it off with the “TransactionConfiguration” annotation and in each method you define you can set the rollback as I share the code below, the rest depends on your choice

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
@Transactional
@TransactionConfiguration(defaultRollback = false)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class AppDAOTest {

    @Autowired
    private AppService appService;

    private final static String parentCatName = "TESTPARENTCATEGORY";
    private final static String childCatName = "TESTCHILDCATEGORY";
    private final static String grandChildCatName = "TESTGRANDCHILDCATEGORY";
    private final static String postName = "TESTPOST";
    private final static String userName = "TESTUSER";
    private final static String userName2 = "TESTUSERTEST";
    private Date date = new Date();

    private static long prantCatId;
    private static long childCatId;
    private static long grandChildCatId;

    @Before
    public void setUp() throws Exception {

    }

    @After
    public void tearDown() throws Exception {
        //Delete the parent category
        //appService.deleteCategory(appService.getCategoryByName(parentCatName));
    }

    @Test
    @Rollback(false)
    public void stage01_CreateParentCategoryTest() {
        //Create the parent category
        appService.createCategory(new Category(parentCatName, date, null, null, null));

        //Fetch the parent category
        Category category = appService.getCategoryByName(parentCatName);

        //Check whether the object is not null
        assertNotNull(category);

        //Check the parent category name does match
        assertEquals(parentCatName, category.getCategoryName());
    }
}

How do I test File api in Junit

Reading Time: < 1 minuteI was looking for a way to test Java file apis, especially I’ve such methods which return Java File. I somehow felt that those methods also have to be tested at least a small test case could be conducted. I did check what File api returns at Oracle Api Docs. The Method you’ll observe below called “buildExcelForRemove” method takes up an ArrayList as a parameter and does process the list and produces a File object as an outcome.

So finally I’ve ended up conducting below test case which you will find very simple. I controversially test;

  • the array list to be given to the corresponding method whether it is empty,
  • size of the array list,
  • existence of the file,
  • whether the outcome is a file,
  • given filename in the method does match the produced file’s name,
  • whether the file object is empty.

After I fire up the test case, I observe that the conducted test is successful.

	private File file;	

	@Before
	public void setUp() throws Exception {
	
	}

	@After
	public void tearDown() throws Exception {
		
	}

	@Test
	public void stage01_BuildExcelForRemoveWithData() {
		file = officeService.buildExcelForRemove(fullreportDetails);
		assertNotNull(fullreportDetails);
		assertEquals(1, fullreportDetails.size());
		assertTrue(file.exists());
		assertTrue(file.isFile());
		assertEquals(buildExcelForRemoveFileName, file.getName());
		assertNotNull(file);
	}

Spring JUnit and Mockito Integration/Configuration and Mock Test

Reading Time: 2 minutesIn this post roll, I’d like to show how to combine Spring, JUnit and Mockito to test a target application. Simply mocking in my definition is to set dummy data for DAO objects. The target source may have accurate data for us to test depending on given data set, in this case where the mocking plays important role in software testing. You can find further readings on the internet for the concepts. I am more interested in exposing the configuration and conducting a simple test case. First of all I’ll give you sample config of my application set, and explain further steps. I’ll walk through giving the source code.

The project hierarchy as follows;

  • src/main/java: where all the interfaces stay
  • src/test/java: where the test classes stay
  • src/test/resources: where spring context configuration stays

Maven Dependency

<dependency>
	<groupId>org.mockito</groupId>
	<artifactId>mockito-all</artifactId>
	<version>1.9.5</version>
</dependency>

DatabaseDAO Interface

public interface DatabaseDAO {	
	public String acquireUserUnitDescription(String usernumber);
}

DatabaseDAOImpl Class

@Override
	public String acquireUserUnitDescription(String usernumber) {
			...
		return unitDescription;
	}

DatabaseService Interface

public interface DatabaseService {	
	public String acquireUserUnitDescription(String usernumber);
}

DatabaseServiceImpl Class

@Autowired
DatabaseDAO databaseDAO;
	public String acquireUserUnitDescription(String usernumber) {
		return databaseDAO.acquireUserUnitDescription(usernumber);
 }

DatabaseDaoTest Class

package com.test.dao;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

import org.junit.After;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.akbank.service.DatabaseService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:*applicationContext-test.xml")
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DatabaseDAOTest {
	
	@Autowired
	@Mock
	DatabaseService dbService;
	
	@Before
	public void setUp() throws Exception {
	MockitoAnnotations.initMocks(this);
	when(dbService.acquireUserUnitDescription("999332822")).thenReturn("Development");
	}

	@After
	public void tearDown() throws Exception {
	}
	
	@Test
	public void testMethod(){
		assertEquals("Development", dbService.acquireUserUnitDescription("999332822"));
	}
}

Output

SpringJUnitMockito

Here as you I mocked the object and the method “acquireUserUnitDescription” called with “999332822” value, then the returned value will always be “Development”

You don’t have to set the when case in the setup area, you can define it in your method as well.