2015-11-06 77 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);