{"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/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/descriptor/ClassBasedTestDescriptor.java#L364-L400","documentation":"Thrown by ClassBasedTestDescriptor.invokeTestInstanceFactory() when a registered TestInstanceFactory.createTestInstance() throws a throwable that is not already a TestInstantiationException. The engine wraps the original exception (appending its message if present) in a TestInstantiationException so that a failure to construct the instance is reported as a test-instantiation failure rather than an arbitrary engine error.","triggerScenarios":"A TestInstanceFactory whose createTestInstance() throws — e.g. a DI container fails to wire the test class, a reflective instantiation hits an inaccessible constructor, or the factory's internal logic throws a RuntimeException.","commonSituations":"Using a dependency-injection test instance factory where the test class has a missing binding; a factory that calls Class.newInstance() on a class with no no-arg constructor; a factory that queries an external resource during instantiation that is unavailable.","solutions":["Examine getCause() of the TestInstantiationException — it is the original failure from the factory.","Fix the root cause reported by the factory (e.g. add the missing DI binding, fix constructor accessibility).","If the factory throws intentionally, throw a TestInstantiationException directly so the message is preserved verbatim instead of being wrapped.","Add a unit test for the factory outside JUnit to reproduce instantiation in isolation."],"exampleFix":"// before\npublic class MyFactory implements TestInstanceFactory {\n    public Object createTestInstance(TestInstanceFactoryContext ctx, ExtensionContext ext) {\n        return injector.getInstance(ctx.getTestClass()); // throws ConfigurationException -> wrapped\n    }\n}\n// after\npublic class MyFactory implements TestInstanceFactory {\n    public Object createTestInstance(TestInstanceFactoryContext ctx, ExtensionContext ext) {\n        try { return injector.getInstance(ctx.getTestClass()); }\n        catch (ConfigurationException e) {\n            throw new TestInstantiationException(\"DI failed for \" + ctx.getTestClass().getName(), e);\n        }\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Validate the factory can build the instance outside JUnit\nObject instance;\ntry { instance = factory.createTestInstance(new DefaultTestInstanceFactoryContext(MyTest.class, null), mockContext); }\ncatch (Throwable t) { throw new IllegalStateException(\"Factory cannot build \" + MyTest.class, t); }\nassert MyTest.class.isInstance(instance);","typeGuard":null,"tryCatchPattern":"try {\n    // test executes with the factory\n} catch (TestInstantiationException e) {\n    Throwable root = e.getCause();\n    // inspect root for DI/reflective failures and surface them\n}","preventionTips":["Unit-test the TestInstanceFactory in isolation before wiring it into tests.","Throw TestInstantiationException from the factory for known failure modes so messages are not double-wrapped.","Ensure DI bindings/constructor accessibility are in place before the test run."],"tags":["junit-jupiter","extension","test-instance-factory","instantiation"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}