为我似乎无法强制执行的捕获异常创建unittest

时间:2018-03-27 18:36:02

标签: java unit-testing sonarqube

我在这里有这个方法并且它工作正常但是我无法为方法的异常部分创建单元测试,因为我无法强制UnsupportedEncodingException。编码器是常数?!

为了清楚起见,使用的'parse()'方法在对字符串中的参数进行一些操作之后再对其进行编码。

public String encode(final String term) {
    try {
        return URLEncoder.encode(parse(URLDecoder.decode(term, StandardCharsets.UTF_8.name())), StandardCharsets.UTF_8.name());
    } catch (final UnsupportedEncodingException e) {
        log.error("The provided query does not seem to be correctly formatted", e);
        return "";
    }
}

我甚至尝试通过使用类似下面的代码将类中的常量操作到其他东西来创建测试来将此常量操作到其他东西,但它似乎不起作用。我似乎无法强迫这个错误。

public static void injectStaticFinal(final Field declaredField, final Object newValue) throws Exception {
    declaredField.setAccessible(true);
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(declaredField, declaredField.getModifiers() & ~FINAL);
    declaredField.set(null, newValue);
}

编写此测试用例

@Test
public void unsupportedEncodingException() throws Exception {
    final SearchTerm searchTerm = new SearchTerm();
    TestUtil.injectStaticFinal(searchTerm, "UTF_8", "just wrong encoder");
    assertThat(searchTerm.encode("hallo"), is(""));
}

此测试失败,因为永远不会抛出异常......

所以SonarQube告诉我它不在测试中,但在这种情况下我不知道如何???我对代码感到满意,但对声纳消息不满意......

1 个答案:

答案 0 :(得分:2)

通过反射设置UTF_8常量可能会让Sonar满意,但它不会覆盖实际代码,因为它会改变真实实现。 此处您要测试的是,由于不支持字符编码UnsupportedEncodingException,因此会引发UTF-8
由于UTF-8通常得到大多数操作系统的支持,因此并没有真正意义。

你有两种方法。

1)最自然的一个:接受分支不被单元测试覆盖

2)更复杂的方式,我不建议它,但更好的是使用反射和编写棘手的测试:用encoding重载方法,一个额外的参数并提取你的实际代码。<登记/> 你的实际方法(没有参数)可以调用带有UTF-8的重载的方法作为参数 并且您可以通过提供无效的字符集来测试异常情况。