【问题标题】:Creating a unittest for a caught exception that I cannot seem to be able to force为我似乎无法强制捕获的异常创建单元测试
【发布时间】:2018-09-06 07:01:40
【问题描述】:

我在这里有这个方法,它工作正常,但我无法为方法的异常部分创建单元测试,因为我无法强制 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 告诉我它不在测试范围内,但在这种情况下我不知道该怎么做???我对代码很满意,但对声纳消息不满意......

【问题讨论】:

  • 测试该异常没有意义。它永远不会发生,因为任何 JVM 都必须支持 UTF8。但是您应该使用 StandardCharSets.UTF8 而不是您自己的常量,并从 catch 块中抛出 IllegalStateException 而不是返回不正确的结果。只需忽略声纳警告。该工具应该帮助你,而不是奴役你。
  • 我完全同意第一个并感谢您的提示。我也不想要任何声纳问题,所以它变成了完成它的测试,然后它变成了一种挫败感:-)。我不同意第二部分,因为在这种情况下,空字符串正是我想要的。
  • 并且过于精确:您可能会在 sonarqube 中看到结果,但这是您的覆盖工具(JaCoCo ?)告诉您分支未被覆盖。我支持该帖子上的所有答案:无需对此进行测试,将其作为覆盖率的百分比接受它是可以的。

标签: java unit-testing sonarqube


【解决方案1】:

通过反射设置 UTF_8 常量可能会让 Sonar 满意,但它不会覆盖实际代码,因为它会更改实际实现。
在这里您要测试的是 UnsupportedEncodingException 被抛出,因为字符编码 UTF-8 不受支持。
这并没有真正的意义,因为大多数操作系统通常都支持 UTF-8。

你有两种方法。

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

2) 更复杂的方式,我不建议这样做,但使用反射和编写棘手的测试要好得多:使用附加参数 encoding 重载方法并提取您的实际代码。
您的实际方法(不带参数)可以使用UTF-8 作为参数调用重载方法。
而且您可以通过提供无效字符集来测试异常场景。

【讨论】:

  • 是的,我也是这么想的,但不接受分支 :-) 我不喜欢因为这个原因更改我的代码,因为它并没有使它更简单,甚至更容易破坏。 ..
  • @Ivonet 实现类很重要,但测试类也很重要。我不会写一个棘手的/不可维护的测试来保持一个好的实现我会接受的。这就是为什么我同意第一个选项更好。
  • 是的,完全同意...争取第一个 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 2012-12-14
  • 1970-01-01
  • 2020-10-02
相关资源
最近更新 更多