如何使用JUnit5 Launcher指定测试类实例执行测试?
JUnit5 编程式执行自定义实例的测试方法
JUnit Jupiter本身并不支持直接传入已创建好的测试实例来执行测试——它默认会自己负责测试类的实例化逻辑。不过你可以通过自定义测试实例工厂绕开默认逻辑,实现用自己构造的带依赖参数的实例执行测试。
具体实现步骤:
自定义TestInstanceFactory
实现JUnit的TestInstanceFactory接口,在createTestInstance方法里返回你自己构造的MyTest实例,把自定义的依赖参数通过构造函数注入进去。示例代码:
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestInstanceFactory; import org.junit.jupiter.api.extension.TestInstanceFactoryContext; import org.junit.jupiter.api.extension.TestInstantiationException; public class CustomTestInstanceFactory implements TestInstanceFactory { // 可传入自定义依赖参数,或从上下文动态获取 private final Object testDependency; public CustomTestInstanceFactory(Object testDependency) { this.testDependency = testDependency; } @Override public Object createTestInstance(TestInstanceFactoryContext factoryContext, ExtensionContext extensionContext) throws TestInstantiationException { // 返回自行构造的测试实例 return new MyTest(testDependency); } }给测试类绑定自定义工厂
在MyTest类上添加@ExtendWith注解,指定使用上面的自定义工厂:import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(CustomTestInstanceFactory.class) public class MyTest { private final Object dependency; // 带参数的构造函数 public MyTest(Object dependency) { this.dependency = dependency; } @Test public void testSomething() { // 测试逻辑中可使用注入的dependency System.out.println("测试执行,依赖参数:" + dependency); } }编程式执行测试
如果工厂需要动态传递参数(比如运行时确定的someParameter),要在创建Launcher时把工厂实例注册进去,而非直接用类名:import org.junit.platform.launcher.Launcher; import org.junit.platform.launcher.LauncherDiscoveryRequest; import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; import org.junit.platform.launcher.core.LauncherFactory; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; public class TestExecutor { public static void main(String[] args) { Object someParameter = "自定义依赖参数"; // 创建带参数的自定义工厂实例 CustomTestInstanceFactory factory = new CustomTestInstanceFactory(someParameter); // 创建Launcher并注册扩展 Launcher launcher = LauncherFactory.create(launcherConfig -> launcherConfig.enableExtensions(factory) ); // 构建测试请求,指定测试类 LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() .selectors(selectClass(MyTest.class)) .build(); // 执行测试 launcher.execute(request); } }
补充说明:
- 如果需要给不同测试用例传递不同参数,可以利用
ExtensionContext的存储功能,在执行测试前把参数存入上下文,再在工厂里取出使用。 - 这种方式通过JUnit扩展机制接管实例创建逻辑,完全符合框架规范,不会破坏生命周期回调、测试报告等原有特性。
内容的提问来源于stack exchange,提问作者Ellen Spertus
相关产品推荐
相关产品推荐

