google/guava · error · FactoryMethodReturnsNullException

%s returns null and cannot be used to test instance methods.

Error message

%s returns null and cannot be used to test instance methods.

What it means

ClassSanityTester auto-generates instances of a class (via constructors or static factory methods) so it can exercise equals/hashCode/toString and null checks. It calls createInstance(), which invokes the factory through invoke(); if the call returns null, a FactoryMethodReturnsNullException is thrown because a null instance cannot be used to test instance methods. The accompanying invoke() assert also requires any null-returning factory to be annotated @Nullable.

Source

Thrown at android/guava-testlib/src/com/google/common/testing/ClassSanityTester.java:771

    if (defaultValue != null) {
      return defaultValue;
    }
    @SuppressWarnings("unchecked") // ArbitraryInstances always returns generics-safe dummies.
    T value = (T) ArbitraryInstances.get(rawType);
    if (value != null) {
      return value;
    }
    if (rawType.isInterface()) {
      return new SerializableDummyProxy(this).newProxy(type);
    }
    return null;
  }

  private static <T> T createInstance(Invokable<?, ? extends T> factory, List<?> args)
      throws FactoryMethodReturnsNullException, InvocationTargetException, IllegalAccessException {
    T instance = invoke(factory, args);
    if (instance == null) {
      throw new FactoryMethodReturnsNullException(factory);
    }
    return instance;
  }

  private static <T> @Nullable T invoke(Invokable<?, ? extends T> factory, List<?> args)
      throws InvocationTargetException, IllegalAccessException {
    T returnValue = factory.invoke(null, args.toArray());
    if (returnValue == null) {
      Assert.assertTrue(
          factory + " returns null but it's not annotated with @Nullable", isNullable(factory));
    }
    return returnValue;
  }

  /**
   * Thrown if the test tries to invoke a constructor or static factory method but failed because
   * the dummy value of a constructor or method parameter is unknown.
   */

View on GitHub (pinned to 94f39958ba)

Solutions

  1. Register non-null dummy values for the factory's parameters with tester.setDefault(type, value) or tester.setDistinctValues(type, v1, v2) so the factory returns a real instance.
  2. Provide an explicit instance via the tester's set API (e.g. tester.set(containerClass, instance)) or point it at a factory that never returns null for the test inputs.
  3. If the null return is intentional, annotate the factory method with @Nullable so invoke() tolerates it, and supply a second non-null-returning factory for instance-level tests.
  4. Exclude the null-returning factory from instance-method testing and test those methods separately with a hand-built instance.

Example fix

// before: factory returns null for default args
tester.doTestEquals(MyClass.class);
// FactoryMethodReturnsNullException: of(...) returns null...

// after: supply a value so the factory returns a real instance
tester.setDefault(Config.class, Config.defaults())
      .doTestEquals(MyClass.class);
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on ClassSanityTester, ensure every factory it will invoke
// returns non-null for the dummy values; pre-register those values.
ClassSanityTester tester = new ClassSanityTester();
for (Invokable<?,?> f : factoriesUnderTest) {
  Object probe = safeInvoke(f, dummyArgs); // your helper
  if (probe == null) {
    tester.setDefault(/* param type */, knownNonNullValue);
  }
}

Try / catch

// FactoryMethodReturnsNullException is checked; catch it where you drive the tester
// only to skip a class, not to mask a real problem.
try {
  tester.doTestEquals(MyClass.class);
} catch (FactoryMethodReturnsNullException e) {
  // supply custom values and retry, or exclude the class
  throw AssumptionViolatedException? // skip via JUnit assumeNoException(e)
}

Prevention

When it happens

Trigger: Calling ClassSanityTester.doTestEquals(Class), doTestNulls(Class), doTestSerializableEqualityInterfaces(Class), or any method that needs a live instance, on a type whose only factory/constructor returns null for the dummy argument values the tester generated.

Common situations: Testing a class whose static factory returns null for some inputs (e.g. caching/interning factories, Optional-style wrappers); factories legitimately annotated @Nullable; the tester could not synthesize non-null values for all parameters so it fell through to a null-returning path.

Related errors


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