2013-02-27 57 views
1

我需要測試合同義務程序。
我沒有看到任何直接測試這種方法的方法。這違反了Single Responsibility Principle,只是做了太多事情。
我會ロ知道,如何安全地提取到新的方法或類下列職責:按單責任原則重構方法

public void askUserPathAndWord() { 

     BufferedReader bufferedReader = new BufferedReader(
       new InputStreamReader(System.in)); 
     String path; 
     String whatFind; 
     BlockingQueue<File> queue = new LinkedBlockingQueue<File>(); 

     try { 
      System.out.println("Please, enter a Path and Word" 
        + "(which you want to find):"); 
      System.out.println("Please enter a Path:"); 
      path = bufferedReader.readLine(); 
      System.out.println("Please enter a Word:"); 
      whatFind = bufferedReader.readLine(); 

      if (path != null && whatFind != null) { 

       File endOfWorkFile = new File("GameOver.tmp"); 
       CountDownLatch latch = new CountDownLatch(2); 

       FolderScan folderScan = new FolderScan(path, queue, latch, 
         endOfWorkFile); 
       FileScan fileScan = new FileScan(whatFind, queue, latch, 
         endOfWorkFile); 

       Executor executor = Executors.newCachedThreadPool(); 
       executor.execute(folderScan); 
       executor.execute(fileScan); 

       latch.await(); 
       System.out.println("Thank you!"); 
      } else { 
       System.out.println("You did not enter anything"); 
      } 

     } catch (IOException | RuntimeException e) { 
      System.out.println("Wrong input!"); 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      System.out.println("Interrupted."); 
      e.printStackTrace(); 
     } 
    } 

Qustions:
我們如何能夠做到安全接下來的步驟:

  • 問用戶的詞和路徑;給定一個單詞,使用正確的參數(Factory)創建一個FileScan ;
  • 給定路徑,使用正確的參數(Factory)創建一個 FolderScan;
  • 給定兩個 可運行和一個鎖存器,創建一個ExecutorService,將它們排隊,並在鎖存器上等待 。

回答

1

這是我會怎樣refactorize該方法中,主要使用IDE的提取方法有共同的新代碼斷言的東西太多了感。最好爲該方法編寫一個測試,以確保重構沒有破壞任何東西。

class PathAndWord { 
    final String path; 
    final String whatFind; 

    PathAndWord(String path, String whatFind) { 
     this.path = path; 
     this.whatFind = whatFind; 
    } 

    boolean isProperlyInitialized() { 
     return path != null && whatFind != null; 
    } 
} 

public void askUserPathAndWord() { 
    try { 
     tryToAskUserPathAndWord(); 
    } catch (IOException | RuntimeException e) { 
     System.out.println("Wrong input!"); 
     e.printStackTrace(); 
    } catch (InterruptedException e) { 
     System.out.println("Interrupted."); 
     e.printStackTrace(); 
    } 
} 

private void tryToAskUserPathAndWord() throws IOException, InterruptedException { 
    PathAndWord pathAndWord = readPathAndWord(); 

    if (pathAndWord.isProperlyInitialized()) { 
     performScan(pathAndWord, "GameOver.tmp"); 
     System.out.println("Thank you!"); 
    } else { 
     System.out.println("You did not enter anything"); 
    } 
} 

private PathAndWord readPathAndWord() throws IOException { 
    System.out.println("Please, enter a Path and Word (which you want to find):"); 

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); 

    String path = readPath(bufferedReader); 
    String whatFind = readWord(bufferedReader); 
    return new PathAndWord(path, whatFind); 
} 

private String readPath(BufferedReader bufferedReader) throws IOException { 
    System.out.println("Please enter a Path:"); 
    return bufferedReader.readLine(); 
} 

private String readWord(BufferedReader bufferedReader) throws IOException { 
    System.out.println("Please enter a Word:"); 
    return bufferedReader.readLine(); 
} 

private void performScan(PathAndWord pathAndWord, String endOfWorkFileName) throws InterruptedException { 
    BlockingQueue<File> queue = new LinkedBlockingQueue<File>(); 

    File endOfWorkFile = new File(endOfWorkFileName); 
    CountDownLatch latch = new CountDownLatch(2); 

    FolderScan folderScan = new FolderScan(pathAndWord.path, queue, latch, 
      endOfWorkFile); 
    FileScan fileScan = new FileScan(pathAndWord.whatFind, queue, latch, 
      endOfWorkFile); 

    Executor executor = Executors.newCachedThreadPool(); 
    executor.execute(folderScan); 
    executor.execute(fileScan); 

    latch.await(); 
} 
+0

如何通過'resolve(Path ..)'正確檢查用戶的路徑輸入genal?並且會證明程序不會「倒下」。 – 2013-02-27 19:50:50

+0

我不確定這個問題是否正確... – 2013-02-27 20:11:27

+0

要確定重構是正確的,你應該有自動測試(或者進行手動測試),它覆蓋了方法功能的100%。在現實世界中,您將測試一些功能(最常見的和一些邊緣情況)。那樣可以讓你確信重構是正確的。但是,你必須測試它。 – 2013-02-28 08:21:13

3

與大多數重構一樣,安全的第一步是測試目前的方法。 然後將代碼重構爲具有必要責任的邏輯組 - 在整個過程中,您以前編寫的測試不應該中斷。 然後你就可以放棄你原來的測試,測試支持的測試,僅僅做出你已經寫好

+0

在stert測試之前,我們是否可以根據[單一職責原則](http://en.wikipedia.org/wiki/Single_responsibility_principle)來分解方法?使代碼可讀性更簡單。 – 2013-02-27 13:22:23

+1

這可能是可能的,但它只適用於簡單的情況。在更復雜的代碼中,如果您的重構破壞了某些內容,可能很難找到問題所在。另一方面,如果您在重構之前進行測試,您將能夠一步一步地重構它,因此可能的錯誤將很容易被發現。 – 2013-02-27 13:32:58