声纳规则S2699:并非所有断言都被识别为有效断言

时间:2016-08-27 06:53:16

标签: java sonarqube

我们使用Java插件4.1运行Sonarqube 5.6.1并且使用Sonar规则S2699遇到一些麻烦(测试应包括断言)。

使用此示例测试类

import mypackage.Citit1543Dummy;
import mypackage.Citit1543OtherDummy;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.MockitoAnnotations;

import java.util.Arrays;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isIn;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.core.IsNot.not;
import static org.mockito.Matchers.notNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.junit.Assert.assertThat;

public class Citit1543Test {

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test1() {
        assert true;
    }

    @Test
    public void test2() {
        Assert.assertTrue(1 > (2-3));
    }

    @Test
    public void test3() {
        Assert.assertFalse(1 > (100-1));
    }

    @Test
    public void test4() {
        Assert.assertThat("test", 1, is(1));
    }

    @Test
    public void test5() {
        Assert.assertArrayEquals(new String[0], new String[0]);
    }

    @Test
    public void test6() {
        Assert.assertEquals(1 > 0, true);
    }

    @Test
    public void test7() { // asserts in another method
        test7asserts(1, 1);
    }

    private void test7asserts(int a, int b) {
        Assert.assertTrue(a == b);
    }

    @Test
    public void test8() {
        test8asserts(1, 2);
    }

    private void test8asserts(int a, int b) {
        Assert.assertNotSame(a, b);
    }

    @Test
    public void test9() {
        Citit1543Dummy dummy = new Citit1543Dummy();
        dummy.otherDummy = mock(Citit1543OtherDummy.class);
        dummy.doSomething();
        verify(dummy.otherDummy, times(1)).doSomething();
    }

    @Test
    public void test10() {
        Citit1543Dummy dummy = new Citit1543Dummy();
        dummy.otherDummy = mock(Citit1543OtherDummy.class);
        dummy.doSomething();
        test10verifies(dummy.otherDummy);
    }

    private void test10verifies(Citit1543OtherDummy otherDummy) {
        verify(otherDummy, times(1)).doSomething();
    }

    @Test
    public void test11() {
        Assert.assertThat("test", "", not(1));
    }

    @Test
    public void test12() {
        Assert.assertThat("test", 1, lessThan(2));
    }

    @Test
    public void test13() {
        Long[] arr = new Long[] { 1L, 2L, 3L, 4L };
        assertThat("Just testing", arr, is(new Long[] {
            1L, 2L, 3L, 4L
        }));
    }
}

我们的Sonarqube实例标记测试用例test1(断言语句未被识别),test7(在另一种方法中断言语句),test8(相同),test10( Mockitos verify在另一种方法中),test11test13作为没有断言的方法。我非常确定还有很多方法无法识别(是的,不幸的是,我们在项目中使用了一堆不同的模拟/测试框架)。

目前,只要其中一个断言/验证无法识别,我们就会开始//NOSONAR。 是否有一种简单的方法可以将这些方法包含在有效的断言中?

1 个答案:

答案 0 :(得分:4)

您陈述的许多问题都是已知的,并且确实(以某种形式的另一种)标记为FP: test1:当前流分析忽略断言语句。请参阅群组中的this post

案例test7,test8和test10与缺乏没有跨程序分析有关:它们是有效的案例,但当前流程不知道(例如)test7assert是另一种方法的有效断言语句。请参阅群组中的this post

您的其他案件也会在S2699的测试中产生误报。我希望一旦SonarSource开发人员阅读这个主题,他们就会创建一张票来解决test11 / 13中的案例。但由于我不是他们的开发者,我当然不能保证。

至于:

  

是否有一种简单的方法可以将这些方法包含在有效的断言中?

不,有效断言是在S2699的代码中定义的,不是参数。你的一些案例需要更复杂的流程分析,而最后一对案例似乎归结为一些缺失的定义或过于严格的定义,但我并没有深入研究它们产生FP的原因。