1

Please help me write Junit for this piece of code using Mockito /Powermock, Finding it difficult due to lamda expression and executor service.

public class myClass {

    ExecutorService executorService;

    public void testMethod(String a){
        Thread thread = new Thread(() -> {
            //logic
            a= testDAo.getStatus();
            while (true) {
                if (Thread.interrupted()) {
                    break;
                }

                if (a() != "done" || a() != "fail") {
                    Thread.yield();
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                    }
                } else {
                    break;
                }
            }
        }
        Future task = executorService.submit(thread);

        while (!task.isDone()) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
            }
        }
    }

}
Akila
  • 1,258
  • 2
  • 16
  • 25
Ram Babu
  • 11
  • 2

1 Answers1

1

Various things here:

  • first of all: for testing executors and parallel execution, using a same thread executor can be extremely helpful (because it takes out the parallel aspect)
  • you have difficulties writing a unit test - because your production code is way too complicated.

Thus the real answer is: step back and improve your production code. Why again are you pushing a thread into an executor service?

The executor service is already doing things on a thread pool (at least that is how you normally use them). So you push a thread into a thread pool, and then you have code that waits "two" times (first within that thread, and then outside on the future). That just adds a ton of complexity for small gain.

Long story short:

  • I would get rid of that "inner thread" - just have the executor task wait until the result becomes available
  • Then: if lambda's give you trouble - then don't use them. Just create a named small class that implements that code. And then you can write unit tests for that small class. In other words: don't create huge "units" that do 5 different things. The essence of a good unit is to one thing (single responsibility principle!). And as soon as you follow that idea testing becomes much easier, too.
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thanks for your input. I could get this working using the below code. We let the actual thread execute and I mocked all the logic inside the thread using Mockito and Powermock.Spy @SpyExecutorService executorService= Executors.newFixedThreadPool(2); – Ram Babu Dec 06 '17 at 06:26
  • My honest opinion: wrong approach. You kept your **hard to test** complicated production code - and you worked around the symptoms by using PowerMock. That is exactly why I find PowerMock to be a bad choice. Because it encourages people to keep their bad design ... – GhostCat Dec 06 '17 at 07:37