2015-08-26 138 views
-1

我很難找到一種方法來單元測試一些使用多線程的代碼。下面是給我的問題代碼:java單元測試ExecutorService

public class ThreadHandler { 
    private ExecutorService executorService; 
    private boolean isFinished = false; 

    public void start() { 
    isFinished = false; 
    executorService = Executors.newFixedThreadPool(10); 
    } 

    public void stop() { 
    isFinished = true; 
    executorService.shutdown(); 
    } 

    public void listen(final ServerSocket serverSocket) throws IOException { 
    Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
     Socket socket = null; 
     try { 
      while (!isFinished) { 
      socket = serverSocket.accept(); 
      executorService.submit(new ClassIWantToMockOut(socket)); 
      } 
     } catch (IOException e) { 
      ... 
     } finally { 
      try { 
      socket.close(); 
      } catch(IOException e) { 
      ... 
      } 
     } 
     } 
    }; 

    this.createThread(runnable); 
    } 

    public void createThread(Runnable runnable) { 
    Thread serverThread = new Thread(runnable); 
    serverThread.start(); 
    } 
} 

我想用嘲諷了ClassIWantToMockOut(插座)來測試方法。但據我所知,不可能嘲笑一個類的構造函數。有什麼我可以做的,使這個代碼更單元測試友好?

+0

「下面是給我的問題的代碼:」,什麼問題? – dnuka

回答

0

這就是工廠是。定義一個創建ClassIWantToMockOut的新實例的工廠。

public class CIWTMOFactory { 
    ClassIWantToMockOut newInstance(ServerSocket serverSocket) { 
     return new ClassIWantToMockOut(serverSocket); 
    } 
} 

然後給你的ThreadHandler類的兩個構造函數。一個接受一個工廠對象作爲參數,另一個使用默認工廠。

class ThreadHandler { 
    private static final CIWTMOFactory defaultFactory = new CIWTMOFactory(); 
    private final CIWTMOFactory ciwtmoFactory; 

    public ThreadHandler() { 
     ciwtmoFactory = defaultFactory; 
     ... 
    } 

    public ThreadHandler(CIWTMOFactory ciwtmoFactory) { 
     this.ciwtmoFactory = ciwtmoFactory; 
     ... 
    } 

    public void listen(...) throws ... { 
     Runnable runnable = new Runnable() { 
      @Override 
      public void run() { 
       ... 
       executorService.submit(ciwtmoFactory.newInstance(socket)); 
       ... 
      }; 
     ... 
    } 
... 
} 

現在你的單元測試可以通過一個返回模擬ClassIWantToMockOut對象的工廠。


工廠模式是,我不知道名字的更一般模式的一個特例。問題是,你想單元測試類C,從包P調用一堆static方法。解決的辦法是,您可以定義一個新類PAdapter,其中有許多實例方法,並且每個實例方法只會從包P調用具有相同名稱和參數的靜態方法。

你後,重新寫入類C通過的PAdapter實例打算讓所有的「靜態」的方法調用,您將能夠編寫單元測試C是通過在模擬/存根/假的/無論PAdapter實例。