当前位置: 首页 > 知识库问答 >
问题:

SonarQube为带有断言的单元测试发出“向该测试用例添加至少一个断言”?

鲁财
2023-03-14

我对SonarQube有问题,我的几个单元测试都有问题,引发了以下问题:

为此测试用例添加至少一个断言。

每个测试用例都类似于此格式(其中许多断言被委托给具有公共断言的方法,以避免重复):

@Test
public void companyNameOneTooLong() throws Exception {
    AddressFormBean formBean = getValidBean();
    formBean.setCompanyNameOne("123456789012345678901234567890123456");

    assertViolation(validator.validate(formBean), "companyNameOne", "length must be between 0 and 35");
}

private void assertViolation(Set<ConstraintViolation<AddressFormBean>> violations, String fieldname, String message) {
    assertThat(violations, hasSize(1));
    assertEquals(fieldname, violations.iterator().next().getPropertyPath().iterator().next().getName());
    assertEquals(message, violations.iterator().next().getMessage());
}

现在,很明显,我可以从私有方法中提取这三个断言,并将它们放在测试方法中,但我正在多次执行相同的检查(在不同的字段上)。

所以,我想我会尝试通过(重新)抛出AssertionError来模拟断言方法的行为:

private void assertViolation(Set<ConstraintViolation<AddressFormBean>> violations, String fieldname, String message) throws AssertionError {
    try {
        assertThat(violations, hasSize(1));
        assertEquals(fieldname, violations.iterator().next().getPropertyPath().iterator().next().getName());
        assertEquals(message, violations.iterator().next().getMessage());
    } catch (AssertionError e) {
        throw e;
    }
 }

不幸的是,这种方法也不起作用。

JUnit断言方法有什么特别之处/SonarQube特别寻找什么来检查是否为每个测试做出了断言?

或者,是否有其他方法可以实现相同的最终结果(避免重复共享断言代码)?

共有3个答案

谷泽宇
2023-03-14

有时您不需要任何代码或断言,例如,成功加载Spring Boot上下文的测试。在这种情况下,为了防止在测试中不会抛出任何异常时出现声纳问题,可以使用以下代码部分:

@Test
void contextLoads() {
    Assertions.assertDoesNotThrow(this::doNotThrowException);
}

private void doNotThrowException(){
    //This method will never throw exception
}
夹谷成仁
2023-03-14

如果您不希望从测试中抛出任何异常,这可以是一种解决方法:

@Test(expected = Test.None.class /* no exception expected */)

或者,可以抑制测试方法/测试类的警告:

@SuppressWarnings("squid:S2699")
司徒捷
2023-03-14

SonarQube Java Analyzer的规则S2699(测试应包括断言)不执行跨过程分析,只探索被识别为测试方法的方法体(通常用测试注释)。

因此,如果在执行测试方法时将被调用的唯一断言是由专用方法完成的(以避免重复),那么该规则将引发一个问题。这是规则的已知限制,我们只有在能够有效地执行跨过程分析时才会处理它。

关于SonarQube在这种情况下提出的问题,您可以安全地将它们标记为不会修复

关于检测到的断言,规则将以下(单元测试)框架中的常规断言方法视为断言:

  • JUnit
  • 节日(1. x
 类似资料:
  • 玩弄Mockito来实现我的服务的单元测试,但由于某种原因,我无法通过我的厚脑袋来实现这一点。我的考试通过了,但我不能确信我做得对。 下面是一个测试count()方法的示例。该方法只是将调用转发到它的存储库,我不想验证仅此而已,没有其他事情发生。这就是我得到的: 我的考试及格了,但我有一些问题。 > 我需要验证吗?我觉得我这样做是因为我想验证personRepository。实际上调用了count

  • 如果它没有返回任何东西,是否可能以某种方式测试它是否停止了这个if语句?我的意思是,我想把某种断言,检查“好吧,上下文是空的,所以它在这个返回时停止了”。 当然,问题是类是空的,为什么我想测试这种方法可能会有问题,但我想听听一些可能性。

  • 我正在使用spock测试Java Spring Boot代码。它在lombok@slf4j注释上获得一个日志记录器。 具有日志调用的虚拟类 斯波克规格 用模拟记录器从这个答案切换真实的帮助器。 我想测试日志调用,但仍然看到日志消息。 我提出了这个解决方案,它使用groovy规范的记录器进行调用。 但是我发现它很冗长,不管我如何为它创建一个帮助器函数。我不是很熟悉函数groovy,将此代码移到函数中

  • 问题内容: 假设我在Python单元测试中具有以下代码: 有没有一种简单的方法可以断言在测试的第二行期间调用了特定方法(在我的情况下)?例如是否有这样的事情: 问题答案: 我为此使用Mock(在py3.3 +上现在是unittest.mock): 对于您的情况,它可能看起来像这样: Mock支持许多有用的功能,包括修补对象或模块的方式以及检查是否调用了正确的东西等。 买者自负! (请当心!) 如果

  • 我对TDD和JUnit有些陌生,我知道我可以为我在代码中实现的方法编写测试用例。 显然,我的代码中有一些方法需要测试几个角落案例来验证方法实现是否正常。由于通常良好的做法是在代码中保持每个方法一个测试方法,因此我必须为这种方法添加多个断言,如本答案所述。https://stackoverflow.com/a/762582/5715934 但是,当我执行测试用例时,我没有获得测试方法中每个断言的测试

  • 问题内容: 我需要创建一个伪的帮助程序类以用于单元测试(注入到测试的类中)。有没有办法在此类中使用TestCase断言? 我想将这些断言用于Fake类执行的一些常见检查。就像是: 问题答案: 您可以创建的实例并在其上调用方法。 在较旧的Python版本(Python 2.7和更早的版本3.0、3.1)上,您需要在类类中传递 现有 方法的名称(通常在子类上传递测试方法的名称)。在这种情况下将: 但是