How do I write a JUnit test case to test threads and events

59,639

Solution 1

You may need to restructure your code so that it can be easily tested.

I can see several distinct areas for testing:

  1. Thread Management code: the code that launches the thread(s) and perhaps waits for results
  2. The "worker" code run in the thread
  3. The concurrency issues that may result when multiple threads are active

Structure your implementation so that Your Thread Management code is agnostic as to the details of the Worker. Then you can use Mock Workers to enable testing of Thread Management - for example a Mock Worker that fails in certain ways allows you to test certain paths in the management code.

Implement the Worker code so that it can be run in isolation. You can then unit test this independently, using mocks for the server.

For concurrency testing the links provided by Abhijeet Kashnia will help.

Solution 2

This is what ConcurrentUnit was created for. The general usage is:

  1. Spawn some threads
  2. Have the main thread wait or sleep
  3. Perform assertions from within the worker threads (which via ConcurrentUnit, are reported back to the main thread)
  4. Resume the main thread from one of the worker threads once all assertions are complete

See the ConcurrentUnit page for more info.

Solution 3

I'm guessing that you may have done your mocking code and may want a simple integration test to ensure that that your server call works.

One of the difficulties in testing threads comes from their very nature - they're concurrent. This means that you're force into writing JUnit test code that is forced to wait until your thread has finished its job before testing your code's results. This isn't a very good way of testing code, and can be unreliable, but usually means that you have some idea about whether you code is working.

As an example, your code may look something like:

@Test
public void myIntegrationTest() throws Exception {

   // Setup your test


   // call your threading code
   Results result = myServerClient.doThreadedCode();

   // Wait for your code to complete
   sleep(5);

   // Test the results
   assertEquals("some value",result.getSomeValue());

}


private void sleep(int seconds) {

    try {
        TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

I really don't like doing this and prefer mocks and agree with the other answers. But, if you need to test your threads, then this is one approach that I find works.

Solution 4

I suggest you use a mocking framework, to confirm that the server call was indeed made. As for the thread unit testing: Unit testing multithreaded applications

Solution 5

The resources provided by Abhijeet Kashnia may help, but I am not sure what you are trying to achieve.

You can do unit testing with mocks to verify your code, that won't test concurrency but will provide coverage. You can write an integration test to verify that the threads are being created and joined in the fashion you expect.However this will not guarantee against concurrency problems. Most concurrent problems are caused by timing bugs which are not predictable and thus can't be tested for accurately.

Share:
59,639
Admin
Author by

Admin

Updated on July 25, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a java code which works in one (main) thread. From the main thread, i spawn a new thread in which I make a server call. After the server call is done, I am doing some work in the new thread and after that the code joins the main thread.

    I am using eclipse Jobs to do the server call.

    I want to know, how do I write a JUnit test case for this.