Genzer
Genzer

Reputation: 2991

Test multithreaded code with JUnit - strange behavior

I'm new to concurrency in Java. I've used Junit to test some of my code but the result is strange. The code snippet below writes nothing to console when I run it with JUnit (Eclipse) though it successfully executes.

@Test
public void testGetNameWithMultithreading() { 

    // code to create IndexFile and DictionaryFile...
    ...
    Thread taskOne = new GetNameTask(packOneIndex, packOneDict);
    Thread taskTwo = new GetNameTask(packTwoIndex, packTwoDict);
    taskOne.start();
    taskTwo.start();
}

However, if I run with main method, it works:

// Switch to test with good-old main method.
public static void main(String args[]) {

        // code to create IndexFile and DictionaryFile...
        ...
        Thread taskOne = new GetNameTask(packOneIndex, packOneDict);
        Thread taskTwo = new GetNameTask(packTwoIndex, packTwoDict);
        taskOne.start();
        taskTwo.start();
}

And this is the task:

public class GetNameTask extends Thread {

    public GetNameTask (IndexFile indexFile, DictionaryFile dictFile) {
        this.dictFile = dictFile;
        this.indexFile = indexFile;
    }

    @Override
    public void run() {
        Dictionary dictionary = new DICTDictionary(indexFile, dictFile);
        System.out.println(dictionary.getName());
    }

    private final IndexFile indexFile;
    private final DictionaryFile dictFile;
}

When constructing DICTDictionary, there is a chain of IO operations to get the name of dictionary from the file.

By any chances that running IO code using multithreading does not work with JUnit?

EDIT: I found out how to make it works. Because JUnit executes the tests on single Threads, so I have to join my 2 small threads to JUnit threads to get expected result. So, this works.

@Test
public void testGetNameWithMultithreading() { 

    // code to create IndexFile and DictionaryFile...
    ...
    Thread taskOne = new GetNameTask(packOneIndex, packOneDict);
    Thread taskTwo = new GetNameTask(packTwoIndex, packTwoDict);
    taskOne.start();
    taskTwo.start();
    try {
        taskOne.join();
        taskTwo.join();
    } catch (InteruptedException ie) {
        ie.printStackTrace();
    }
}

Is there any easier way to test multitheading code with JUnit?

Best regards.

Upvotes: 1

Views: 1671

Answers (2)

duffymo
duffymo

Reputation: 308743

JUnit is notorious for not dealing properly with threads.

I've only been able to get them to work using TestNG. I'd recommend a switch. It should mean little more than a different @Test annotation import and a new JAR in the CLASSPATH.

Upvotes: 2

Omnaest
Omnaest

Reputation: 3096

Your test method has to block the execution until the Threads are done.

Consider using a ThreadPool. See ExecutorService.awaitTemination for more...

Upvotes: 2

Related Questions