0

I have the below code:

public final class JoinableTaskPool<T> extends ABC {

       public Future<T> submit(final Callable<T> task) {
           executorService.submit(new Runnable() {
             public void run() {
                try {
                    final Future<T> result = service.take();
                    try {
                        handler.processResult(result);
                    } catch (final Throwable t) {
                        throw new SearchException("Task has an error", t);
                    }
                } catch (InterruptedException e) {
                    throw new SearchException("Task has an error", e);
                }
            }
          } 
       }
  }

I am trying to write a unit test for this method. Below is the method:

@RunWith(MockitoJUnitRunner.class)
public class TestJoinableTaskPool<T> {

    private JoinableTaskPool<T> pool;

    @Before
    public void setUp() {
        pool = new JoinableTaskPool<T>(1);
    }

    @After
    public void tearDown() {
        pool.shutdown();
    }

    @Test
    public void testSubmit() throws Exception{
        Callable task = (Callable<T>) () -> null;
        Future<T> result = new FutureTask<T>(task);
        Mockito.when(pool.getCompService().take())
                .thenReturn(result);

        Mockito.when(pool.getFinishHandler().processResult(result))
                .thenThrow(RuntimeException.class);

        pool.submit(task);
    }
}

I am getting compilation error at below line saying:

reason: no instance(s) of type variable(s) T exist so that void conforms to T

Mockito.when(pool.getFinishHandler().processResult(result))
                .thenThrow(RuntimeException.class);

How do we get around this? I have tried replacing T as String or any other class, but issue still exists. Passing any() as parameter to processResult does now work as well and I want that method call to throw an exception which assert on.

Any help would be appreciated.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
BigDataLearner
  • 1,388
  • 4
  • 19
  • 40
  • Mockito methods such as `when` only work with mocks, you could start by making `pool` a mock. However, then you wouldn't be testing you code, but a mock. It is unclear what is a dependency of your test (mocking is appropriate) and the code under test (you should not mock). Also, you can't use chaining with mocks `pool.getFinishHandler().processResult(result)` is not valid in a `when` like you are using it. – DCTID Jun 12 '20 at 02:00
  • @DCTID I understand when works only with mocks so Instead of passing result, if I pass any() to the processResult method, still it shows the same error. Or If I make result as `Future result = Mockito.any(Future.class);` , it still gives the same error. – BigDataLearner Jun 12 '20 at 02:24
  • @BigDataLeaner I think this question should be closed, it is unclear how to help you. Maybe try a Mockito [tutorial](https://www.vogella.com/tutorials/Mockito/article.html) there are many others, but please take the SO [tour](https://stackoverflow.com/tour) – DCTID Jun 12 '20 at 03:31
  • Does this code compile at all? `public Future submit(final Callable task)` is supposed to return a `Future` but it doesn't. – Gerold Broser Jun 14 '20 at 01:59

1 Answers1

0

Your test class is generic. Where do you expect the concrete type for it to come from? The message tells it already: "no instance(s) of type variable(s) T exist".

If I remove the type argument from TestJoinableTaskPool and replace all <T>s with a concrete type, e.g. Object, Mockito throws the exception:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

which is comprehensible since .processResult(result) is invoked on a Handler but there isn't any Handler mocked.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107