簡體   English   中英

在單元測試中從 Runnable 捕獲 Java 異常

[英]Catch Java exception from Runnable in Unit test

我有以下代碼

public final class JoinableTaskPool<T> extends ABC {
       private int taskCounter;
       private final Object monitor;
       private final ExtendedThreadPoolExecutor service;
       private final CompletionService<T> compService;

       public Future<T> submit(final Callable<T> task) {
           final Future<T> result = compService.submit(task);
           service.submit(new Runnable() {
             public void run() {
                try {
                    final Future<T> result = compService.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);
                }
            }
          } 
          return result;
       }

  public void join() {
    synchronized (monitor) {
        while (taskCounter != 0) {
            try {
                monitor.wait();
            } catch (InterruptedException e) {
                error(e, "Interrupted in join");
            }
        }
  }
  }

ExtendedThreadPoolExecutor class 定義如下

public class ExtendedThreadPoolExecutor extends ThreadPoolExecutor {

    public ExtendedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if(t != null) {
            throw new SearchException("Error while executing the task", t);
        }
    }
}

我正在嘗試為此方法編寫單元測試。 下面是方法

@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 (expected = SearchException.class)
    public void testSubmit() throws Exception{
        Callable task = (Callable<T>) () -> null;

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

        pool.submit(task);
    }
}

由於在runnable中拋出了SearchException異常,所以沒有辦法在submit方法之外訪問它。 如果我會返回由executorService.submit返回的 Future,我可以執行 future.get() 來獲取異常,但我會返回另一個未來( result變量)。 因此,在編寫單元測試時,我無法拋出異常。

我還重寫了 afterExecute() 以從單元測試中捕獲異常,但找不到調用它的方法。

如何測試從單元測試的可運行對象拋出的異常。 任何幫助,將不勝感激。

撇開他的代碼聞起來一英里遠,你可以做的是創建額外的接口,例如

public interface MyErrorHandler { handleError(Exception e)

在您的執行程序池中實現它並在異常時調用它。 然后您可以使用Mockito.spy來查看是否在MyErrorHandler上調用了該方法(cglib 應該允許您這樣做,即使沒有額外的接口。)

或者,您可以定義應將MyExceptionHandler實例傳遞給執行程序(通過構造函數或設置器),以便您能夠提供此類回調的用例依賴實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM