{"record":{"id":"2e947e5f94ad8051","repo":"junit-team/junit5","slug":"testinstancefactory-s-failed-to-instantiate-tes","errorCode":null,"errorMessage":"TestInstanceFactory [%s] failed to instantiate test class [%s]","messagePattern":"TestInstanceFactory \\[(.+?)\\] failed to instantiate test class \\[(.+?)\\]","errorType":"exception","errorClass":"TestInstantiationException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java","lineNumber":382,"sourceCode":"\n\t\ttry {\n\t\t\tExtensionContext actualExtensionContext = extensionContext.get(testInstanceFactory);\n\t\t\tinstance = testInstanceFactory.createTestInstance(\n\t\t\t\tnew DefaultTestInstanceFactoryContext(getTestClass(), outerInstance), actualExtensionContext);\n\t\t}\n\t\tcatch (Throwable throwable) {\n\t\t\tUnrecoverableExceptions.rethrowIfUnrecoverable(throwable);\n\n\t\t\tif (throwable instanceof TestInstantiationException exception) {\n\t\t\t\tthrow exception;\n\t\t\t}\n\n\t\t\tString message = \"TestInstanceFactory [%s] failed to instantiate test class [%s]\".formatted(\n\t\t\t\ttestInstanceFactory.getClass().getName(), getTestClass().getName());\n\t\t\tif (StringUtils.isNotBlank(throwable.getMessage())) {\n\t\t\t\tmessage += \": \" + throwable.getMessage();\n\t\t\t}\n\t\t\tthrow new TestInstantiationException(message, throwable);\n\t\t}\n\n\t\tif (!getTestClass().isInstance(instance)) {\n\t\t\tString testClassName = getTestClass().getName();\n\t\t\tClass<?> instanceClass = (instance == null ? null : instance.getClass());\n\t\t\tString instanceClassName = (instanceClass == null ? \"null\" : instanceClass.getName());\n\n\t\t\t// If the test instance was loaded via a different ClassLoader, append\n\t\t\t// the identity hash codes to the type names to help users disambiguate\n\t\t\t// between otherwise identical \"fully qualified class names\".\n\t\t\tif (testClassName.equals(instanceClassName)) {\n\t\t\t\ttestClassName += \"@\" + Integer.toHexString(System.identityHashCode(getTestClass()));\n\t\t\t\tinstanceClassName += \"@\" + Integer.toHexString(System.identityHashCode(instanceClass));\n\t\t\t}\n\t\t\tString message = \"TestInstanceFactory [%s] failed to return an instance of [%s] and instead returned an instance of [%s].\".formatted(\n\t\t\t\ttestInstanceFactory.getClass().getName(), testClassName, instanceClassName);\n\n\t\t\tthrow new TestInstantiationException(message);","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java#L364-L400","documentation":"Wraps any non-unrecoverable Throwable thrown by a registered TestInstanceFactory.createTestInstance when instantiating a test class. The factory's own exception is only rethrown as-is if it is already a TestInstantiationException; everything else is rewrapped with the factory class name, test class name, and the original message appended.","triggerScenarios":"A TestInstanceFactory implementation throwing inside createTestInstance - constructor logic failure, reflection error, missing dependency, NPE from the factory body, or an exception bubbling up from the test class constructor.","commonSituations":"DI-based factory (Spring/Guice/Koin) cannot resolve a bean, Kotlin object instantiation fails, factory calls Class.newInstance() on a class with no usable constructor, or the factory returns from a blocking lookup that times out.","solutions":["Read the appended cause message (the literal ': ' prefix plus throwable.getMessage()) and fix the underlying instantiation failure.","Verify all constructor parameters of the test class can be resolved by the factory's DI context.","If you wrote the factory, throw TestInstantiationException directly so users get your message verbatim instead of the wrapped form.","Ensure the factory class is not failing due to a missing classpath dependency it needs to build the instance."],"exampleFix":"// before\n@Override\npublic Object createTestInstance(TestInstanceFactoryContext ctx, ExtensionContext ec) {\n    return myContainer.getBean(ctx.getTestClass()); // throws when bean missing\n}\n// after\n@Override\npublic Object createTestInstance(TestInstanceFactoryContext ctx, ExtensionContext ec) {\n    Class<?> c = ctx.getTestClass();\n    if (!container.containsBean(c))\n        throw new TestInstantiationException(\"No bean for \" + c.getName());\n    return container.getBean(c);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    runTests(MyTest.class);\n} catch (TestInstantiationException e) {\n    log.error(\"Factory {} failed: {}\", e.getMessage(), e.getCause());\n    throw e;\n}","preventionTips":["Ensure your TestInstanceFactory can resolve every dependency the test constructor needs.","Throw TestInstantiationException directly from your factory so users see your message unwrapped.","Unit-test the factory outside JUnit to confirm it can build the instance."],"tags":["test-instance-factory","instantiation","extension","di"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}