在junit中包含try catch的方法的测试异常

时间:2018-06-22 21:02:10

标签: junit4

我下面有代码段。

我想要的是如果getNames()方法捕获异常 (例如InterruptedException), 想检查Got InterruptedException !!!是否打印出来。

有一些方法测试异常的例子 会在Internet中的方法(例如String method1() throws InterruptedException {...})中引发异常。

但不是这种情况。有人有什么想法或想法吗?

public class A {
    public List<String> getNames()
    {
        String addess = "address1";
        int age = 17;

        List<String> names = null;
        try {
            names = getSomeNames(address, sex);
        }
        catch (InterruptedException | ExecutionException e) {
            throw new MyCustomException(e);
        }
        catch(Exception e) {
            throw new MyCustomException(e);
        }

        return names;
    }


    List<String> getSomeNames(String address, int sex) throws InterruptedException, ExecutionException
    {
        // ...
        // throw exceptions... at some point
        //

        return names;                   
    }
}

public class MyCustomException extends Exception {
    public MyCustomException(Throwable e) {

        if (e.getCause() instanceof InterruptedException) {
            // write log
            System.out.println("Got InterruptedException !!!");
        }
        else if (e.getCause() instanceof ExecutionException) {
            // write log
            System.out.println("Got ExecutionException!!!");
        }
        else {
            // write log
        }
    }
}

我尝试了这个,但是测试失败了,并且在catch块中出现了NullPointerException。

@Test  
public void testException() {
    A objA = spy(new A());

    try {
        doThrow(MyCustomException.class).when(objA).getNames();
        objA.getNnames();
    }
    catch (Exception e) {
        System.out.println(e.getCause().toString());  // ==> throws java.lang.NullPointerException here.
    }
}

1 个答案:

答案 0 :(得分:0)

有几种测试方法。

第一个解决方案是将System.out替换为不同的流,并在以后读取。 (我不喜欢这种方法)

  @Test
    void whenSayHi_thenPrintlnCalled() throws IOException {
        PrintStream normalOutput = System.out;
        String result;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream temporalOutput = new PrintStream(baos)) {
            System.setOut(temporalOutput);
            ThatGuy thatGuy = new ThatGuy();
            thatGuy.sayHi();
            result = new String(baos.toByteArray(), StandardCharsets.UTF_8);
        } finally {
            System.setOut(normalOutput);
        }
        assertEquals("Hi", result.trim());
    }

第二个是使用logger而不是System.out。我不仅从测试方面而且从代码设计角度来看,都认为这种方法更好。使用此功能,您只需将logger替换为Mockito.mock,然后用用户Mockito.verify来检查您的logger上的内容。

  @Test
    void whenSayHi_thenCallLogger() {
        Logger logger = Mockito.mock(Logger.class);
        ThatGuy thatGuy = new ThatGuy();
        ReflectionTestUtils.setField(thatGuy, "logger", logger);
        thatGuy.sayHiToLog();
        verify(logger).error("Hi");
    }

正在测试的类如下:

class ThatGuy {
        private static Logger logger = LoggerFactory.getLogger(ThatGuy.class);

        void sayHi() {
            System.out.println("Hi");
        }

        void sayHiToLog() {
            logger.error("Hi");
        }
 }