google/guava · error · IllegalStateException

Call using() before createTestSuite().

Error message

Call using() before createTestSuite().

What it means

Thrown by FeatureSpecificTestSuiteBuilder.checkCanCreate() when you call createTestSuite() without having supplied a subject generator (the factory that produces the collection/map under test). The builder refuses to build a TestSuite because it has no object to test. checkCanCreate() guards the head of createTestSuite() and runs before any tester is instantiated.

Source

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

    List<Class<? extends AbstractTester>> testers = getTesters();

    TestSuite suite = new TestSuite(name);
    for (@SuppressWarnings("rawtypes") // class literals
    Class<? extends AbstractTester> testerClass : testers) {
      @SuppressWarnings("unchecked") // getting rid of the raw type, for better or for worse
      TestSuite testerSuite =
          makeSuiteForTesterClass((Class<? extends AbstractTester<?>>) testerClass);
      if (testerSuite.countTestCases() > 0) {
        suite.addTest(testerSuite);
      }
    }
    return suite;
  }

  /** Throw {@link IllegalStateException} if {@link #createTestSuite()} can't be called yet. */
  protected void checkCanCreate() {
    if (subjectGenerator == null) {
      throw new IllegalStateException("Call using() before createTestSuite().");
    }
    if (name == null) {
      throw new IllegalStateException("Call named() before createTestSuite().");
    }
    if (features == null) {
      throw new IllegalStateException("Call withFeatures() before createTestSuite().");
    }
  }

  @SuppressWarnings("rawtypes") // class literals
  protected abstract List<Class<? extends AbstractTester>> getTesters();

  private boolean matches(Test test) {
    Method method;
    try {
      method = extractMethod(test);
    } catch (IllegalArgumentException e) {
      logger.finer(Platform.format("%s: including by default: %s", test, e.getMessage()));

View on GitHub (pinned to 94f39958ba)

Solutions

  1. Call the builder's using(...) (or the subclass-specific generator-setting method) with a TestContainerGenerator before createTestSuite(), e.g. ListTestSuiteBuilder.using(new TestListGenerator<>()).
  2. If your builder subclass takes the generator in its constructor, make sure you are instantiating the subclass that sets subjectGenerator rather than the abstract base.
  3. Verify the builder chain order: using(...) -> named(...) -> withFeatures(...) -> createTestSuite().

Example fix

// before
TestSuite suite = ListTestSuiteBuilder.using()
    .named("MyList")
    .withFeatures(ListFeature.GENERAL_PURPOSE)
    .createTestSuite();

// after
TestSuite suite = ListTestSuiteBuilder.using(new MyListGenerator())
    .named("MyList")
    .withFeatures(ListFeature.GENERAL_PURPOSE)
    .createTestSuite();
Defensive patterns

Strategy: validation

Validate before calling

// Validate builder state before calling createTestSuite().
FeatureSpecificTestSuiteBuilder<?,?> b = ListTestSuiteBuilder.using(gen);
// using(...) must be called; verify the generator is non-null.
java.util.Objects.requireNonNull(gen, "subject generator is required by using()");
TestSuite suite = b.named("MyList").withFeatures(ListFeature.GENERAL_PURPOSE).createTestSuite();

Prevention

When it happens

Trigger: Calling builder.createTestSuite() after constructing a TestSuiteBuilder subclass (e.g. ListTestSuiteBuilder, MapTestSuiteBuilder) without first invoking the builder method that installs a TestContainerGenerator/subject generator (the using(...) family or a constructor that accepts one). subjectGenerator == null at line 208 trips the guard.

Common situations: Copying an existing Guava-testlib suite wiring and forgetting the .using(new MyCollectionGenerator()) line; refactoring a builder chain and dropping the generator; creating a fresh builder via the no-arg constructor of a subclass that does not set subjectGenerator.

Related errors


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