2015-11-06 91 views
0

我正在編寫一些單元測試,並嘗試從我的代碼中覆蓋儘可能多的東西。現在我想編寫一個測試來驗證本地主機的名稱。在單元測試中捕獲未知主機異常

的方法是這樣的:

public static String getLocalhostName() { 
     try { 
     return InetAddress.getLocalHost().getHostName(); 
     } 
     catch (final UnknownHostException e) { 
     throw new RuntimeException(e.getMessage()); 
     } 
    } 

和我的測試:

@Test 
public void testGetLocalhostName() { 
    final String host = getLocalhostName(); 
    Assert.assertEquals("mycomputer", host); 
} 

的問題是我怎麼能爲了也覆蓋了從main方法的catch塊重構呢?

+0

使用Mockito框架,如Mockito,EasyMock – kswaughs

回答

-2
public static String getLocalhostName() throws UnknownHostException { 
     try { 
     return InetAddress.getLocalHost().getHostName(); 
     } 
     catch (final UnknownHostException e) { 
     throw new RuntimeException(e.getMessage()); 
     } 
    } 

@Test 
public void testGetLocalhostName() throws UnknownHostException { 
    final String host = getLocalhostName(); 
    Assert.assertEquals("mycomputer", host); 
} 

,並在主要使用在try..catch或聲明它拋出異常或UnknownHostException異常

0

這將讓您的測試覆蓋範圍。

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import java.net.InetAddress; 
import java.net.UnknownHostException; 

import static org.mockito.BDDMockito.given; 


@RunWith(PowerMockRunner.class) 
@PrepareForTest(InetAddress.class) 
public class Mocker { 

    @Mock 
    private java.net.InetAddress mockedAddress; 

    @Test(expected = RuntimeException.class) 
    public void testGetLocalHostName() throws Exception { 

     //given 
     PowerMockito.mockStatic(InetAddress.class); 
     given(InetAddress.getLocalHost()).willReturn(mockedAddress); 
     given(mockedAddress.getHostName()).willThrow(UnknownHostException.class); 

     //when 
     getLocalhostName(); 
    } 

    public static String getLocalhostName() { 
     try { 
      return InetAddress.getLocalHost().getHostName(); 
     } catch (final UnknownHostException e) { 
      throw new RuntimeException(e.getMessage()); 
     } 
    } 

} 

但由於它不驗證被拋出RuntimeException之前預期的代碼運行是不能令人滿意的。

捕獲異常可能會更好,然後您可以驗證對模擬類的調用。

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import java.net.InetAddress; 
import java.net.UnknownHostException; 

import static org.mockito.BDDMockito.given; 
import static org.mockito.Mockito.verify; 


@RunWith(PowerMockRunner.class) 
@PrepareForTest(InetAddress.class) 
public class Mocker { 

    @Mock 
    private java.net.InetAddress mockedAddress; 

    @Test 
    public void testGetLocalHostName() throws Exception { 

     //given 
     PowerMockito.mockStatic(InetAddress.class); 
     given(InetAddress.getLocalHost()).willReturn(mockedAddress); 
     given(mockedAddress.getHostName()).willThrow(UnknownHostException.class); 

     //when 
     try { 
      getLocalhostName(); 
     } catch (RuntimeException e) { 
      PowerMockito.verifyStatic(); 
      InetAddress.getLocalHost(); 
      verify(mockedAddress).getHostName(); 
     } 
    } 

    public static String getLocalhostName() { 
     try { 
      return InetAddress.getLocalHost().getHostName(); 
     } catch (final UnknownHostException e) { 
      throw new RuntimeException(e.getMessage()); 
     } 
    } 

} 
1

作爲一個經驗法則,你不應該嘲笑外部庫。通過嘲諷,你可以假設它的行爲,可能不是這種情況,或者將來可能會發生什麼變化。你只應該模擬你控制的代碼,並編寫你的測試代碼。

在這種情況下,我會將InetAddress.getLocalHost().getHostName()提取到另一個類HostNameProvider,然後執行依賴注入,就像John Williams的回答中一樣,但不使用功率模擬。然後你會有兩個測試你當前的課程和一個HostNameProvider(只有開心的路徑)。

但是,實際應用測試驅動開發時會發生什麼?您編寫測試,編寫實現並且不編譯,因此您必須通過添加try-catch來修復它。在這一點上,我會認爲沒有開發人員是不負責任的,只是吞下異常。如果有人這樣做,你有靜態分析 - IntelliJ和Sonar都會強調這一點。總之 - 我不會測試它。

我也建議修改模板,所以當你生成try-catch時,它會自動在catch中添加throw new RuntimeException(e);