junit-team/junit5 · error · TestInstantiationException
TestInstanceFactory [%s] failed to return an instance of [%s
Error message
TestInstanceFactory [%s] failed to return an instance of [%s] and instead returned an instance of [%s].
What it means
Thrown by ClassBasedTestDescriptor.invokeTestInstanceFactory() when the factory returns an object that is not an instance of the test class (getTestClass().isInstance(instance) is false). When the returned class name equals the test class name (same FQCN loaded by different ClassLoaders), identity-hash codes are appended to help disambiguate classloader collisions.
Source
Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java:400
throw new TestInstantiationException(message, throwable);
}
if (!getTestClass().isInstance(instance)) {
String testClassName = getTestClass().getName();
Class<?> instanceClass = (instance == null ? null : instance.getClass());
String instanceClassName = (instanceClass == null ? "null" : instanceClass.getName());
// If the test instance was loaded via a different ClassLoader, append
// the identity hash codes to the type names to help users disambiguate
// between otherwise identical "fully qualified class names".
if (testClassName.equals(instanceClassName)) {
testClassName += "@" + Integer.toHexString(System.identityHashCode(getTestClass()));
instanceClassName += "@" + Integer.toHexString(System.identityHashCode(instanceClass));
}
String message = "TestInstanceFactory [%s] failed to return an instance of [%s] and instead returned an instance of [%s].".formatted(
testInstanceFactory.getClass().getName(), testClassName, instanceClassName);
throw new TestInstantiationException(message);
}
return instance;
}
private Object invokeTestClassConstructor(@Nullable Object outerInstance, ExtensionRegistry registry,
ExtensionContextSupplier extensionContext) {
Constructor<?> constructor = ReflectionUtils.getDeclaredConstructor(getTestClass());
return executableInvoker.invoke(constructor, outerInstance, extensionContext, registry,
InvocationInterceptor::interceptTestClassConstructor);
}
private void invokeTestInstancePreConstructCallbacks(TestInstanceFactoryContext factoryContext,
ExtensionRegistry registry, ExtensionContextSupplier context) {
registry.stream(TestInstancePreConstructCallback.class).forEach(extension -> executeAndMaskThrowable(
() -> extension.preConstructTestInstance(factoryContext, context.get(extension))));
}View on GitHub (pinned to 956246301e)
Solutions
- Make the factory return an instance created from ctx.getTestClass() directly (e.g. getTestClass().getDeclaredConstructor().newInstance()).
- If using a proxy/mock, ensure the proxy class extends or implements the test class and is loaded by a ClassLoader consistent with the test.
- For ClassLoader collisions, unify the loader so the test class is loaded once; the @identityHashCodes in the message diagnose this case.
- Return a non-null value — null is reported as the 'returned an instance of [null]' variant of this same error.
Example fix
// before
public Object createTestInstance(TestInstanceFactoryContext ctx, ExtensionContext ext) {
return SomeOtherClass.INSTANCE; // wrong type
}
// after
public Object createTestInstance(TestInstanceFactoryContext ctx, ExtensionContext ext) {
Class<?> c = ctx.getTestClass();
try { return c.getDeclaredConstructor().newInstance(); }
catch (Exception e) { throw new TestInstantiationException("fail", e); }
} Defensive patterns
Strategy: validation
Validate before calling
// In the factory, validate before returning
Object instance = buildInstance(ctx.getTestClass());
if (instance == null || !ctx.getTestClass().isInstance(instance)) {
throw new TestInstantiationException("Factory returned wrong type: " + (instance == null ? "null" : instance.getClass()));
}
return instance; Type guard
static boolean factoryReturnsCorrectType(TestInstanceFactory f, Class<?> testClass, ExtensionContext ctx) {
Object inst = f.createTestInstance(new DefaultTestInstanceFactoryContext(testClass, null), ctx);
return inst != null && testClass.isInstance(inst);
} Prevention
- Always instantiate from ctx.getTestClass() rather than a cached Class reference.
- Never return null from a TestInstanceFactory.
- For proxy/mock factories, verify the proxy class is loaded by a ClassLoader consistent with the test.
When it happens
Trigger: A TestInstanceFactory returns null, returns an instance of a different class, or returns an instance of the right class name loaded by a different ClassLoader than the one JUnit used to discover the test.
Common situations: A mock/proxy factory returning a subclass proxy that is not assignable; OSGi or custom ClassLoader setups where the test class is loaded twice; a factory that returns a shared singleton of a sibling class by mistake; returning a Mockito mock of the class when mocking final classes is disabled (mock is a different generated class).
Related errors
- The following TestInstanceFactory extensions were registered
- TestInstanceFactory [%s] failed to instantiate test class [%
- Can only resolve @TempDir <target> of type java.nio.file.Pat
- temp directory with non-default file system cannot be inject
- Failed to publish path
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/787d6ec285f255f4.json.
Report an issue: GitHub.