0

Suppose, I have a class SomeClass with a method void process(). The implementation of this method is smth like new Thread(this::someOtherMethod).start (need to execute only someOtherMethod in a particular thread).

Having written down a unit test for this method:

SomeClass class= new SomeClass(anObjectToWorkWith); class.process(); assertEquals(expectedObj, anObjectToWorkWith)

I have realised, that as the process method executes in a particular thread, an assertEquals instruction is called before the process method is completed.

Therefore, I have a question: is there some way to wait for the process method execution, to make assertEquals be called necessarily after the process.

Thank you in advance.

P.S. Don't propose solutions that use Thread.sleep method or solutions that imply making SomeClass implement Runnable interface, as these solutions don't conform to the tasking.

  • if you make class.process() return the Thread t instance the calling thread can call t.join(). That will wait for the subthread to finish. – bhspencer Dec 07 '17 at 18:57
  • @bhspencer the thing is that the SomeClass class implements an interface with a `void process()` method, that is why i am limited with such solutions. –  Dec 07 '17 at 19:01
  • In that case you could add another method called wait() to the instance of SomeClass. Have the Thread be a member of SomeClass and in wait() call t.join(); – bhspencer Dec 07 '17 at 19:02
  • look into using a https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html. Wait the main testing thread and call countdown from the spawned threads. – Doctor Parameter Dec 07 '17 at 19:10
  • I appreciate the quick comeback. – GhostCat Dec 08 '17 at 09:31

1 Answers1

1

You simply have hard to test code here.

When your code under test creates a new thread instance and uses that - then there is simply no good way to write reasonable unit tests.

Instead: consider changing your code under test.

For example: instead of using low level threads, turn to an ExecutorService. And then use a same thread executor for your tests. Because that allows you to turn your multi-threaded problem into a single-threaded one. Just by using a different kind of executor.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • This. Test the internally created `Runnable` for being able to create the result it's supposed to without the concurrency, best you can do. – daniu Dec 07 '17 at 19:05