Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test class which implements Runnable with Junit

I have a class implements Runnable like this

  public Processor implements Runnable{

  public void run() {
     while (true) {
     //some code
     sendRequest(object);
      }
   }
}

 public void sendRequest(Object, object){
 // do something to send the event
  }
}

And in other pre-load class. I use

Processor processor = new Processor();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(processor)

So my question is how can I unit test sendRequest method is called or not?

like image 677
HenlenLee Avatar asked Nov 12 '18 21:11

HenlenLee


2 Answers

Separate the concerns : the Runnable and the logic associated.
It will make in addition your code mode testable.
You could extract sendRequest() in a Foo class that the Processor class depends on. Then you have just to mock this Foo class in your test and verify that the sendRequest() method was invoked.

For example :

 public Processor implements Runnable{

  private Foo foo;

  public Processor(Foo foo){
    this.foo = foo;
  }

  public void run() {
     while (true) {
       //some code
       foo.sendRequest(object);
     }
   }
}

And the test :

@Mock
Foo fooMock;

@Test
public void run() {
    Processor processor = new Processor(fooMock);
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(processor);
    executor.awaitTermination(someTime, TimeUnit.SECONDS);
    Mockito.verify(fooMock).sendRequest(...);   
}
like image 113
davidxxx Avatar answered Oct 20 '22 04:10

davidxxx


i believe you want to test only implemented run() method, so you can call the method directly using Processor object or you can create a thread and pass runnable object to it and call Thread.start()

If sendRequest(Object object) method is doing any external operations i will suggest you to mock that method

public class ThreadTest {

@Test(//throws some exception)
public void shouldThrowSomeException() {
    Processor exThread = new Processor ();
    exThread.run(); //or
    Thread t = new Thread(exThread);
     t.start()

    }
}

Mocking for mocking here

@Test(//throws some exception)
public void shouldThrowSomeException() {
    Processor exThreadmock = mock(Processor.class);
    when(exThreadmock.sendRequest(anyObject))
    .thenThrow(SomeException.class)
    Thread t = new Thread(exThread);
     t.start()

    }
like image 43
Deadpool Avatar answered Oct 20 '22 06:10

Deadpool