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

Prerequisites

Java 8

Eclipse

Gradle

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.

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 the Gradle project in Eclipse

Create java project using the following build.gradle script

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'
}

Build the project

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

Writing thread class

Write below Thread class

package com.jeejava.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.jeejava.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.

Running the above Junit class will pass the test.

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

Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

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