具有非 Junit 断言方法的 TestMethodWithoutAssertion 的 JQassistant 规则

JQassistant rule for TestMethodWithoutAssertion with non-Junit assert methods

我们的项目使用 assertj 库中的 assert 方法以及一些单元测试方法。因此,当前用于搜索 assert 方法的密码规则不会识别如下所示的 assert 方法并将它们标记为违规。

assertThat("x").isEqualTo("Y");在单元测试方法中。

如何修改脚本以考虑来自单元测试方法的任何 "assert*" 调用。

      <cypher><![CDATA[
        MATCH
            (c:Type:Class)-[:DECLARES]->(m:Method:JunitTestMethod),
            (m)-[:INVOKES*..10]->(assert:Method)
        WHERE
            assert.signature =~ "void assert.*"
            OR assert.signature =~ "void fail.*"
            OR assert.signature =~ "void verify.*"

        SET
            m:JunitTestWithAssert
        RETURN
            c.fqn AS TestClass, m.name AS TestMethodWithAssert
        ]]></cypher>

示例测试方法:

        @Test
        public void testAssertWithDiffLibrary() {
          String testName = "Hello";
          assertThat(testName).isEqualTo("Hello");
         }

注意:尝试添加 where 子句 "OR assert.name =~ ".assert."" 但未检测到这些断言。

会是

"OR assert.name =~ ".*assert.*"" 

但它的缺点是,凡是名称中包含assert的方法都会被标记出来。 注意点后面的星星。

鉴于您想使用提供的 "junit4:TestMethodWithoutAssertion" 约束,我建议使用 http://buschmais.github.io/jqassistant/doc/1.3.0/#junit4:AssertMethod 概念的 AssertJ 版本:

<concept id="assertj:AssertMethod">
    <description>Labels all assertion methods declared by org.assertj.core.api.Assertions with "Assertj" and "Assert".</description>
    <cypher><![CDATA[
        MATCH
                (assertType:Type)-[:DECLARES]->(assertMethod)
            WHERE
            assertType.fqn = 'org.assertj.core.api.Assertions'
            and assertMethod.signature =~ '.*assertThat.*'
        SET
        assertMethod:Assertj:Assert
        RETURN
                assertMethod
        ]]></cypher>
</concept>

所以你现在的组定义如下:

<group id="default">
    <includeConcept refId="assertj:AssertMethod" />
    <includeConstraint refId="junit4:TestMethodWithoutAssertion" />
</group>

现在您提供的示例方法已得到正确处理。

看看 Spring PetClinic 演示应用程序:它在 assertj.adoc:

中提供了一个概念 "assertj:AssertMethod"
[[assertj:AssertMethod]]
[source,cypher,role=concept]
.Mark all assertThat methods of 'org.assertj.core.api.Assertions' with "AssertJ" and "Assert".
----
MATCH
  (assertType:Type)-[:DECLARES]->(assertMethod)
WHERE
  assertType.fqn = 'org.assertj.core.api.Assertions'
  and assertMethod.signature =~ '.* assertThat.*'
SET
  assertMethod:AssertJ:Assert
RETURN
  assertMethod
----

然后由 test.adoc 中的约束引用:

[[test:TestMethodWithoutAssertion]]
[source,cypher,role=constraint,requiresConcepts="junit4:TestMethod,assertj:AssertMethod,spring-test-web:Assert"]
.All test methods must perform at least one assertion (within a call hierarchy of max. 3 steps).
----
MATCH
  (testType:Test:Type)-[:DECLARES]->(testMethod:Test:Method)
WHERE
  NOT (testMethod)-[:INVOKES*..3]->(:Method:Assert)
RETURN
  testType AS DeclaringType,
  testMethod AS Method
----