Writing Junit Test on Java Thread

Introduction

In this tutorial you will see how to write test case on Java thread using junit. Writing junit test on Java thread will show an example on single threaded environment.

Prerequisites

Java 1.8, Eclipse, Gradle 4.10.2

How to Structure Code Block?

It is advisable to structure the code in such a way so that the code could be easily tested on several distinct areas:

  1. the code that launches the thread and wait for result.
  2. the worker code that runs in the thread.
  3. the concurrency issue may occur when multiple threads are active.

Structure your implementation of the worker code so that it could be run in isolation and it would be possible to run junit independently.

One of the difficulties in testing threads come from concurrency nature. Therefore, you are writing junit test cases where your are forced to wait using method Thread.sleep(1000) or some other mechanism until the thread has finished its job before you can test your code’s results. This is not a very good idea and could be unreliable but this way at least you could check whether your code is working or not.

Example

The following example will show you how do we write a junit test on java thread class. For this example we will create a Gradle based Java project in Eclipse and write a Thread class on which we will perform Junit testing.

Creating Project

Create gradle based Java project in Eclipse and update the build.gradle script as given below:

apply plugin: 'java'
repositories {
    mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
	testCompile 'junit:junit:4.12'
    testCompile 'org.powermock:powermock-api-mockito2:1.7.0RC2'
    testCompile 'org.powermock:powermock-module-junit4:1.7.0'
    testCompile 'org.powermock:powermock-core:1.7.0'
    testCompile 'org.powermock:powermock-module-junit4-rule:1.7.0'
}

Building the Project

Run gradle clean build command to build the project and download the required jar libraries.

Writing Thread Class

Write below Thread class. As said previously we are starting a single thread in the below class.

package com.roytuts.thread;
public class ThreadClass {
	public static void main(String[] args) {
		ThreadClass threadClass = new ThreadClass();
		threadClass.doSomthingDifferent();
	}
	public void doSomthingDifferent() {
		Runnable task = () -> {
			doSomthing();
			System.out.println("----------------------------------------");
			System.out.println("Task is running");
			System.out.println("----------------------------------------");
			for (int i = 1; i <= 25; i++) {
				System.out.println("Thread-" + i);
			}
		};
		// start the thread
		new Thread(task).start();
	}
	private void doSomthing() {
		System.out.println("inside doSomthing()");
	}
}

Writing Junit

Write below Junit class for the above Thread class.

package com.roytuts.thread;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ThreadClass.class)
public class ThreadClassTest {
	private ThreadClass threadClass;
	ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
	@Test
	public void testDoSomthingDifferent() throws Exception {
		threadClass = Mockito.spy(new ThreadClass());
		Thread thread = Mockito.mock(Thread.class);
		PowerMockito.whenNew(Thread.class).withParameterTypes(Runnable.class).withArguments(captor.capture())
				.thenReturn(thread);
		threadClass.doSomthingDifferent();
		captor.getValue().run();
		// verify that doSomethingDifferent() method has been executed at least once
		Mockito.verify(threadClass, Mockito.times(1)).doSomthingDifferent();
	}
}

We need to test on real object of ThreadClass that’s why I have used spy() method on ThreadClass and mock() method on Java’s Thread class.

Testing

Running the above Junit class will pass the test.

To know more on ArgumentCaptor class you can read documentation hereĀ https://static.javadoc.io/org.mockito/mockito-core/2.6.9/org/mockito/ArgumentCaptor.html

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *