0

Our project has few Unit Tests in which the asserts are passed as a lambda or consumer to the test class. Example as below. How to write a cypher rule constraint such the asserts are identified and the method is not flagged as without assert. Currently using junit4:TestMethodWithoutAssertion

Test Method :

     @Test 
     public void testSuccessfulIdempotency(){
     transportConsumerFlow.accept(Mockito.mock(TransRequest.class), 
     (t)->{
           assertEquals(t, expectedResponseMessage);
      });
     }

In the sample above, the assert is actually present and valid. But the concept junit4:AssertMethod could not detected may be because it is present as a consumer instead of a direct invocation in Test method.

skpraveen
  • 183
  • 1
  • 5
  • 18

1 Answers1

1

Lambda expressions are currently not explicitly support by jQAssistant but you may identify them as synthetic static methods (as generated by the bytecode) using the following concept:

MATCH
  (type:Type)-[:DECLARES]->(lambda:Method)
WHERE
  exists(lambda.synthetic)
  and exists(lambda.static)
  and lambda.name starts with("lambda$")
SET
  lambda:Lambda
WITH
  type, lambda
MATCH
  (type)-[:DECLARES]->(method:Method)
WHERE
  method <> lambda
  and method.firstLineNumber <= lambda.firstLineNumber
  and method.lastLineNumber >= lambda.lastLineNumber
MERGE
  (method)-[:DECLARES_LAMBDA]->(lambda)
RETURN
  method, collect(lambda)

You'll not see any INVOKES relations from the test methods to the lambda methods, so a custom constraint with the following cypher query needs to be used (based on junit4:TestMethodWithoutAssertion):

MATCH
  (testType:Type)-[:DECLARES]->(testMethod:Test:Method)
WHERE
  NOT (testMethod)-[:INVOKES|DECLARES_LAMBDA*..3]->(:Method:Assert)
RETURN
  testType AS DeclaringType,
  testMethod AS Method
Dirk Mahler
  • 1,186
  • 1
  • 6
  • 7
  • :Thanks for response! However, the clause and method.firstLineNumber <= lambda.firstLineNumber and method.lastLineNumber >= lambda.lastLineNumber doesn't seem to work. Seems that firstLineNumber,lastLineNumber attributes are not available. – skpraveen Apr 30 '18 at 16:50
  • Just tried it with the following test class and it worked: public class LambdaTest { @Test public void lambda() { Stream.of("1", "2").forEach(s -> assertThat(s, notNullValue())); } } Have you verified if you can execute the query in the Neo4j browser by starting the server (mvn jqassistant:server) and if it returns results? – Dirk Mahler Apr 30 '18 at 19:54
  • I just executed the above given concept in the Neo4j browser and it didn't give any result."no - rows found". Any pre-requisites ? minimum version ? – skpraveen Apr 30 '18 at 21:15
  • After upgrading to jqassistant version 1.3.0 and maven compiler to enforce 1.8 Java version, this approach worked ! Thanks much ! – skpraveen May 01 '18 at 09:28
  • One correction in the above concept. Instead of RETURN method, collect(lambda) It could be Just RETURN method – skpraveen May 01 '18 at 09:29
  • I've just created a sample branch "jqa-lambda" in the demo application (https://github.com/buschmais/spring-petclinic/), just have a look at jqassistant/java8.adoc and jqassistant/test.adoc. A test class LambdaTest provides provides two test methods (with/without assertion), the later is reported by jQA. – Dirk Mahler May 01 '18 at 13:16