如何在 Junit 测试中覆盖 catch 块?

How to cover catch block in Junit testing?

我正在尝试将测试 class 覆盖到 100%。但是,由于我无法测试 catch 块,所以我最多只能做到 90%。谁能告诉我如何覆盖 catch 块。

下面是我要测试的class:

public class UnsubscribeXmlTransformer {

    public Map<String, Object> process(Map<String, Object> requestMap) {

        String inputStream = requestMap.get(NeoConstants.INPUTSTREAM).toString();

        Smooks smooks;
        try {
            smooks = new Smooks("Unsubscribe-smooks.xml");

            JavaResult javaResult = new JavaResult();


            smooks.filterSource(new StringSource(inputStream), javaResult);


            UnsubscribeDetailsVO unsubscribeDetailsVO = (UnsubscribeDetailsVO) javaResult
                    .getBean("unsubscribeDetailsVO");

            requestMap.put("unsubscribeDetailsVO", unsubscribeDetailsVO);

        } catch (IOException | SAXException e) {        }

        return requestMap;
    }

}

这是我的测试 class:

public class UnsubscribeXmlTransformerTest {
    Map<String, Object> requestMap = null;  

    @Before
    public void prepareRequestMap() {
        requestMap = new HashMap<>();
        String inputStream = "some xml tags";

        requestMap.put(NeoConstants.INPUTSTREAM, inputStream);      
    }


    @Test
    public void processTest() throws Exception {
        UnsubscribeXmlTransformer ref = new UnsubscribeXmlTransformer();
        Map<String, Object> result = ref.process(requestMap);

        Assert.assertNotNull("Result is not null", result);
        Assert.assertFalse("Result is not empty", result.isEmpty());
        Assert.assertTrue("Result contains key named inputStream", result.containsKey(NeoConstants.INPUTSTREAM));
        Assert.assertTrue("Result contains key named unsubscribeDetailsVO", result.containsKey("unsubscribeDetailsVO"));
        Assert.assertTrue("Value with key unsubscribeDetailsVO is an instance of UnsubscribeDetailsVO", result.get("unsubscribeDetailsVO") instanceof UnsubscribeDetailsVO);
    }

    @Test(expected = IOException.class)
    public void processTestForException() {
        UnsubscribeXmlTransformer ref = new UnsubscribeXmlTransformer();

        // how to cover                 
    }
}

您可以在您的 requestMap 上使用 Mockito.spy,并在应该抛出异常时模拟案例。然后(如 jannis 所指出的)您可以使用 AssertJ 的流利 API 来验证没有抛出异常(您在 catch 子句中将其静音),例如

@Test
public void process_shouldCatchException() throws Exception{
    UnsubscribeXmlTransformer sut = new UnsubscribeXmlTransformer();
    Map<String, Object> requestMap = Mockito.spy(new HashMap<>());
    when(requestMap.put(eq("unsubscribeDetailsVO"), any()))
        .thenThrow(IOException.class);
    assertThatCode(() -> sut.process(requestMap))
        .doesNotThrowAnyException();
}

这里当我们执行classUnderTest.handleError(clienthttpresponse);它会在 java class 中抛出异常 ..为了覆盖 java class 中 catch 块中的代码,我们需要在 try 块中编写以下代码并且 Assert.fail() ,那么它不会立即抛出错误,而是进入 catch 块。

try {
            Mockito.when(clienthttpresponse.getBody()).thenReturn(targetStream);
            classUnderTest.handleError(clienthttpresponse);
            fail();
        }catch(Exception e) {
            System.out.println(e.getClass()+""+e.getMessage());
        }