如何使用Mockito模拟和编写单元测试以尝试捕获块

时间:2020-06-23 13:22:02

标签: java spring-boot unit-testing mockito resttemplate

在下面的示例中,我尝试使用Mockito测试catch和try块。而且,当引发CustomException时,我想使用第二个主机调用该方法。谢谢。

private static void getDetails()
{
    final String host1 = "http://localhost:8080/springrestexample/employee/id";
   
    final String host2 = "http://localhost:8080/springrestexample/student/id";

     
    RestTemplate restTemplate = new RestTemplate();
    String result = null;
    try {
        String result = restTemplate.getForObject(host1, String.class);
    } catch(CustomException customException) {
       String result = restTemplate.getForObject(host2, String.class);
    }
    return result;
}

2 个答案:

答案 0 :(得分:1)

是否有可能将restTemplate作为参数传递给该方法。

(如果是,那么)

使用org.mockito.Mockito -> mock(),您可以像下面这样模拟,

RestTemplate restTemplateMock = mock(RestTemplate.class);
when(restTemplateMock.getForObject(host1)).thenThrow(CustomException.class);

将此模拟对象传递给您的方法,它将在try内引发异常。

更新:供您参考的测试用例样本。

@Test
public void testGetDetails()
{
  RestTemplate restTemplateMock = mock(RestTemplate.class);
  when(restTemplateMock.getForObject(host1)).thenReturn(SOME_STRING);
  String result = //call your method
  assertThat(result).isEqualTo(SOME_STRING);
}

@Test
public void testGetDetailsUsesOtherHostWhenExceptionIsThrown()
{
  RestTemplate restTemplateMock = mock(RestTemplate.class);
  when(restTemplateMock.getForObject(host1)).thenThrow(CustomException.class);
  when(restTemplateMock.getForObject(host2)).thenReturn(SOME_STRING);
  String result = //call your method
  assertThat(result).isEqualTo(SOME_STRING);
}

当您需要使用相同的模拟对象时,

RestTemplate myRestTemplateMock = mock(RestTemplate.class);

@Test
public void testGetDetails()
{
  when(myRestTemplateMock.getForObject(host1)).thenReturn(SOME_STRING);
  String result = //call your method
  assertThat(result).isEqualTo(SOME_STRING);
}

@Test
public void testGetDetailsUsesOtherHostWhenExceptionIsThrown()
{ 
  
  when(myRestTemplateMock.getForObject(host1)).
                                  thenThrow(CustomException.class);
  when(myRestTemplateMock.getForObject(host2)).thenReturn(SOME_STRING);
  String result = //call your method
  assertThat(result).isEqualTo(SOME_STRING);
}

答案 1 :(得分:1)

好吧,首先,您的原始方法需要如下所示。 (由于通常的做法是我们不测试私有方法,如果您需要测试静态方法,则除了Mockito(PowerMock)以外,还需要其他东西)

public class Example {

    @Autowired
    public RestTemplate restTemplate;

    public  String restTemplateTest()
    {
        final String host1 = "http://localhost:8080/springrestexample/employee/id";

        final String host2 = "http://localhost:8080/springrestexample/student/id";

        String result;
        try {
             result = restTemplate.getForObject(host1, String.class);
        } catch(CustomException customException) {
             result = restTemplate.getForObject(host2, String.class);
        }
        return result;
    }
}

下面是上述方法的样本测试。

    public class ExampleTest {
    
       @Mock
       private RestTemplate restTemplate;
    
       @InjectMocks
       private Example testExample;
    
       @BeforeEach
       public void setUp()
       {
           MockitoAnnotations.initMocks(this);
       }
    
        @Test
        public void restTemplateTest() {
    
            Mockito.when(restTemplate.getForObject(Mockito.eq("http://localhost:8080/springrestexample/employee/id"), Mockito.eq(String.class)))
                    .thenThrow(CustomException.class);
    
            Mockito.when(restTemplate.getForObject(Mockito.eq("http://localhost:8080/springrestexample/student/id"), Mockito.eq(String.class)))
                    .thenReturn("expected");
    
            testExample.restTemplateTest();
    
            // if exception thrown , then rest template mock will invoke 2 times, otherwise
            // 1
            Mockito.verify(restTemplate, Mockito.times(2)).getForObject(Mockito.anyString(), Mockito.eq(String.class));
    
        }

}

下面是测试没有发生异常的情况的方法。

@Test
public void restTemplateTest_when_no_exception() {

    Mockito.when(restTemplate.getForObject(Mockito.eq("http://localhost:8080/springrestexample/employee/id"), Mockito.eq(String.class)))
            .thenReturn("expectedString");

    String actual = testExample.restTemplateTest();

    // if exception not thrown , then rest template mock will invoke 1 times, otherwise
    // 1
    Mockito.verify(restTemplate, Mockito.times(1)).getForObject(Mockito.anyString(), Mockito.eq(String.class));

    Assert.assertEquals("expectedString",actual);
}