我有一個類,其中使用Runtime.getRuntime()從命令行執行腳本並獲取進一步處理的結果。如何在編寫JUnit時使用Runtime.getRuntime()?
但是,當我爲這個類編寫JUnit時,我無法找到一種方法來模擬/避免此Runtime.getRuntime()。exec()。
我不能使用EasyMock或PowerMock或除Mockito以外的任何其他模擬API。
請給我一種方法來解決這個問題,因爲這影響了代碼覆蓋率。
我有一個類,其中使用Runtime.getRuntime()從命令行執行腳本並獲取進一步處理的結果。如何在編寫JUnit時使用Runtime.getRuntime()?
但是,當我爲這個類編寫JUnit時,我無法找到一種方法來模擬/避免此Runtime.getRuntime()。exec()。
我不能使用EasyMock或PowerMock或除Mockito以外的任何其他模擬API。
請給我一種方法來解決這個問題,因爲這影響了代碼覆蓋率。
您必須重構。提取Runtime.getRuntime().exec()
成一個單獨的類:
public class Shell {
public Process exec(String command) {
return Runtime.getRuntime().exec(command);
}
}
現在insted的調用getRuntime()
的明確注入Shell
類莫名其妙地類測試:通過將其傳遞到構造
public class Foo {
private final Shell shell;
public Foo(Shell shell) {
this.shell = shell;
}
//...
shell.exec(...)
}
在JUnit測試純粹注入嘲笑Shell
類:
@Mock
private Shell shellMock;
new Foo(shellMock);
旁註:是的,我是不是創建一個Shell
接口與一個實現。你介意嗎? Mockito不是。獎金:您現在可以驗證是否正確的過程被稱爲:
verify(shellMock).exec("/usr/bin/gimp");
Tomasz Nurkiewicz提供了一個美好的答案。但有一個選擇。
您可以將Runtime.getRuntime()
移動到您正在測試的類中自己的方法中;然後用Mockito間諜進行測試。在Mockito間諜中,你可以用創建模擬Runtime
的版本覆蓋這個特定的方法,然後做任何你喜歡的事情。
但是,Tomasz的方法更簡潔,我推薦徹底。我只是想說,還有另一種方法可以做到,而不訴諸Powermock。
哎呀,大衛,我沒有看到你的答案,然後再次發佈相同。非常感謝您提供一個美妙的解決方案。 – unni
我使用的子類化和壓倒一切的(如邁克爾·C·羽毛書‘與遺留代碼有效地工作’解釋)
假設我們有下面的代碼:
public class CannotChange{
public CannotChange(){}
public void TryingToTest() throws IOException {
...
Process proc = Runtime.getRuntime().exec("command");
...
}
}
提取運行代碼轉換成一個受保護的方法:
public void TryingToTest() throws IOException {
...
Process proc = execute("command");
...
}
protected Process execute(string command){
return Runtime.getRuntime().exec(command);
}
然後在測試類創建擴展CannotChange類並覆蓋一類 執行
public class CannotChangeTest{
private class CannotChangeForTesting extends CannotChange{
public CannotChangeForTesting(){ super(); }
@Override
public Process execute(String command){
return null; //or a mocked object
}
}
@Test
public void TestMethod(){
CannotChange cannotChange = new ForTestCannotChange();
cannotChange.TryingToTest();
}
}
嗨,感謝您的快速回復! – unni
但是,還有其他一些可能嗎?在哪裏我不必更改構造函數?既不使用像'this.shell = shell'這樣的setter – unni
@ user1147417:我沒有看到任何可能性,至少沒有PowerMock。 '靜態'是邪惡的! –