如何在junit的catch子句中覆盖我的记录器

时间:2018-10-09 15:12:36

标签: java logging junit mockito

我正在尝试对我的应用程序进行完整的junit测试,但是在测试记录器消息时遇到问题。

try {
    fillParameters(args);
} catch (ArgumentException e) {
    logger.error(e.getMessage(), e);
    return;
}

这是触发异常的代码:

if (args.length > 3) {
    throw new ArgumentException("Wrong use of the command -> too many args"); 
}

一个测试:

@Test
public void testFillParametersWithTooManyArguments() {
    String[] args = { "...", "...", "...", "..." };
    Throwable e = null;
    try {
        testInstance.fillParameters(args);
    } catch (Throwable ex) {
        e = ex;
    }
    assertTrue(e instanceof ArgumentException); //this test is working as expected
}

当我看一下代码覆盖率时,logger.error(e.getMessage(),e);部分未被覆盖,我应该如何覆盖它?我认为我必须嘲笑记录仪吗?

1 个答案:

答案 0 :(得分:0)

简短回答
测试您实际要测试的代码。

一些信息
第一个代码块中的代码绝不会通过示例单元测试中的代码进行测试。 我假设是因为它看起来像Java代码,并且该问题被标记为Java问题,因此第一个代码块中的代码实际上在某个方法中。 您必须将该方法组合起来,以在该方法的异常捕获块中获得测试覆盖率。

例如:

public void IHateToTellPeopleMyMethodName(final String[] args)
{
    try
    {
        fillParameters(args);
    }
    catch (ArgumentException e)
    {
        logger.error(e.getMessage(), e);
        return;
    }
}

为了获得对catch块的测试覆盖, IHateToTellPeopleMyMethodName方法, 您必须测试 单元测试中的IHateToTellPeopleMyMethodName方法。

此单元测试方法不会测试IHateToTellPeopleMyMethodName方法,因为它不会调用IHateToTellPeopleMyMethodName方法。

@Test
public void testThatInNoWayTestsTheIHateToTellPeopleMyMethodNameMethod()
{
    String[] args = { "...", "...", "...", "..." };

    try
        {
        testInstance.fillParameters(args);
                fail("expected exception not thrown");
    }
        catch (Throwable ex)
        {
            assertTrue(e instanceof ArgumentException);
    }
}

与上面的单元测试代码不同, 该单元测试涵盖了IHateToTellPeopleMyMethodName方法。

@Test
public void testTheIHateToTellPeopleMyMethodNameMethod()
{
    String[] args = { "...", "...", "...", "..." };

    testInstance.IHateToTellPeopleMyMethodName(args);

          verify(mockLogger).error(
                eq(EXPECTED_MESSAGE_TEXT),
                    any(ArgumentException.class));
}

编辑笔记
我的错, any()需要一个class对象作为参数, 不是班级名称。