How do I write a JUnit test case to test threads and events
This is what I created ConcurrentUnit for. The general usage is:
- Spawn some threads
- Have the main thread wait or sleep
- Perform assertions from within the worker threads (which via ConcurrentUnit, are reported back to the main thread)
- Resume the main thread from one of the worker threads once all assertions are complete
See the ConcurrentUnit page for more info.
You may need to restructure your code so that it can be easily tested.
I can see several distinct areas for testing:
- Thread Management code: the code that launches the thread(s) and perhaps waits for results
- The "worker" code run in the thread
- 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.
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.