openrewrite / rewrite-testing-frameworks

OpenRewrite recipes that perform common Java testing migration tasks.
Apache License 2.0
77 stars 73 forks source link

org.openrewrite.java.testing.junit5.AssertThrowsOnLastStatement: NullPointer when Body is null #618

Closed timo-a closed 1 month ago

timo-a commented 1 month ago

What version of OpenRewrite are you using?

I am using

How are you running OpenRewrite?

mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-testing-frameworks:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.testing.junit5.AssertThrowsOnLastStatement

I am using the Maven plugin, and my project is a single module project.

What is the smallest, simplest way to reproduce the problem?

original file

package com.fasterxml.jackson.core.read.loc;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertThrows;

class LocationOfError1173Test {

    @Test
    void parserBackendWithInvalidJson() {
        assertThrows(IllegalStateException.class, () -> { while (System.out != null) {} });
    }
}

This will result in a NullPointer, see below

What is the full stack trace of any errors you encountered?

[ERROR] Failed to execute goal org.openrewrite.maven:rewrite-maven-plugin:5.42.2:run (default-cli) on project jackson-core: Execution default-cli of goal org.openrewrite.maven:rewrite-maven-plugin:5.42.2:run failed: Error while visiting src/test/java/com/fasterxml/jackson/failing/LocationOfError1180Test.java: java.lang.NullPointerException: Cannot invoke "org.openrewrite.java.tree.J$Block.getStatements()" because the return value of "org.openrewrite.java.tree.J$MethodDeclaration.getBody()" is null
[ERROR]   org.openrewrite.java.testing.junit5.AssertThrowsOnLastStatement$1.visitMethodDeclaration(AssertThrowsOnLastStatement.java:60)
[ERROR]   org.openrewrite.java.testing.junit5.AssertThrowsOnLastStatement$1.visitMethodDeclaration(AssertThrowsOnLastStatement.java:55)
[ERROR]   org.openrewrite.java.tree.J$MethodDeclaration.acceptJava(J.java:3651)
[ERROR]   org.openrewrite.java.tree.J.accept(J.java:59)
[ERROR]   org.openrewrite.TreeVisitor.visit(TreeVisitor.java:248)
[ERROR]   org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:318)
[ERROR]   org.openrewrite.java.JavaVisitor.visitRightPadded(JavaVisitor.java:1365)
[ERROR]   org.openrewrite.java.JavaVisitor.lambda$visitBlock$4(JavaVisitor.java:397)
[ERROR]   org.openrewrite.internal.ListUtils.map(ListUtils.java:176)
[ERROR]   org.openrewrite.java.JavaVisitor.visitBlock(JavaVisitor.java:396)
[ERROR]   org.openrewrite.java.JavaIsoVisitor.visitBlock(JavaIsoVisitor.java:88)
[ERROR]   org.openrewrite.java.JavaIsoVisitor.visitBlock(JavaIsoVisitor.java:30)
[ERROR]   org.openrewrite.java.tree.J$Block.acceptJava(J.java:838)
[ERROR]   org.openrewrite.java.tree.J.accept(J.java:59)
[ERROR]   org.openrewrite.TreeVisitor.visit(TreeVisitor.java:248)
[ERROR]   org.openrewrite.TreeVisitor.visitAndCast(TreeVisitor.java:318)
[ERROR]   ...
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

Are you interested in contributing a fix to OpenRewrite?

No

timtebeek commented 1 month ago

Thanks for the report @timo-a ; great to see you've helped Jackson adopt JUnit Jupiter, and are coming back here to report issues.

I've briefly tried to replicate the issue, but so far no luck:

    @Test
    @Issue("https://github.com/openrewrite/rewrite-testing-frameworks/issues/618")
    void lambdaWithWhileLoop() {
        //language=java
        rewriteRun(
          java(
            """
              import org.junit.jupiter.api.Test;

              import static org.junit.jupiter.api.Assertions.assertThrows;

              class MyTest {

                  @Test
                  public void test() {
                      assertThrows(IllegalStateException.class, () -> { while (System.out != null) {} });
                  }
              }
              """
          )
        );
    }

Did I miss anything?

I did notice there was a check on the body being null previously that might have erroneously been removed in https://github.com/openrewrite/rewrite-testing-frameworks/commit/8bfd44ab6d44a675dab19d578800956e0eb71be3 Would restoring that help you think? Ideally that change is then matched up with a unit test that requires it, such that it's not dropped again.

@shivanisky might have some additional context here as well

timo-a commented 1 month ago

So, it seems that the error occurs in two similarly names test classes, and, convinced that the bug is triggered from within the assertion, I didn't notice that the file I was reducing was no longer causing the error...

Please try

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class MyTest {

    @Test
    void test() {
        assertThrows(IllegalStateException.class, () -> System.out.println("foo"));
    }

    public interface InnerInterface {
        String createParser(String input);
    }
}
timtebeek commented 1 month ago

Thanks a lot; that's all I needed indeed. 🥂