google/guava · error · IllegalArgumentException

unable to extract method from test: not a TestCase.

Error message

unable to extract method from test: not a TestCase.

What it means

Thrown by FeatureSpecificTestSuiteBuilder.extractMethod(Test) when the given Test is neither an AbstractTester (which exposes getTestMethodName()) nor a junit TestCase (which exposes getName()). The library needs a reflective Method to read tester annotations and filter tests, so an unrecognized Test type cannot be processed.

Source

Thrown at android/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java:275

      }
      return false;
    }
    return true;
  }

  private static boolean intersect(Set<?> a, Set<?> b) {
    return !disjoint(a, b);
  }

  private static Method extractMethod(Test test) {
    if (test instanceof AbstractTester) {
      AbstractTester<?> tester = (AbstractTester<?>) test;
      return getMethod(tester.getClass(), tester.getTestMethodName());
    } else if (test instanceof TestCase) {
      TestCase testCase = (TestCase) test;
      return getMethod(testCase.getClass(), testCase.getName());
    } else {
      throw new IllegalArgumentException("unable to extract method from test: not a TestCase.");
    }
  }

  protected TestSuite makeSuiteForTesterClass(Class<? extends AbstractTester<?>> testerClass) {
    TestSuite candidateTests = new TestSuite(testerClass);
    TestSuite suite = filterSuite(candidateTests);

    Enumeration<?> allTests = suite.tests();
    while (allTests.hasMoreElements()) {
      Object test = allTests.nextElement();
      if (test instanceof AbstractTester) {
        @SuppressWarnings("unchecked")
        AbstractTester<? super G> tester = (AbstractTester<? super G>) test;
        tester.init(subjectGenerator, name, setUp, tearDown);
      }
    }

    return suite;

View on GitHub (pinned to 94f39958ba)

Solutions

  1. Make sure every test added to the builder's tester suites is a subclass of AbstractTester (preferred) or junit.framework.TestCase.
  2. Avoid wrapping tester instances in custom Test adapters; add the raw AbstractTester subclass via the builder's getTesters() list instead.
  3. If you must filter, use the builder's .suppress(...) / feature-filtering mechanisms rather than replacing the Test objects.

Example fix

// before
class MyDecorator implements Test { /* wraps an AbstractTester */ }
suite.addTest(new MyDecorator(tester));

// after
// Add the AbstractTester subclass directly; let the builder build the suite.
public class MyListAddTester extends AbstractListTester { public void testAdd() { ... } }
Defensive patterns

Strategy: type-guard

Type guard

// Only feed the builder tester classes that are AbstractTester/TestCase subclasses.
static boolean isAcceptableTester(Class<?> c) {
  return AbstractTester.class.isAssignableFrom(c) || junit.framework.TestCase.class.isAssignableFrom(c);
}

Prevention

When it happens

Trigger: A custom Test object (e.g. a TestSuite wrapper, a junit 4-style runner, or a plain Runnable adapted to Test) reaches extractMethod via the matches()/filtering path inside makeSuiteForTesterClass. It is not an AbstractTester or TestCase subclass.

Common situations: Mixing junit 4/5 test styles with the guava-testlib junit 3 TestCase model; wrapping tester classes in a custom suite/decorator that changes the runtime Test type; providing a third-party Test implementation as a tester.

Related errors


AI-assisted analysis of google/guava@94f39958ba (2026-08-13). Data as JSON: /api/errors/da5ed32f1d0f1cff. Report an issue: GitHub.