JUnit5中@BeforeEach可通过ExtensionContext获取Method对象并读取自定义注解,需确保注解含@Retention(RUNTIME);调用context.getRequiredTestMethod()获Method,再用method.getAnnotation()获取注解实例。

OpenJDK 24
OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。
下载
<p>在 JUnit5 中,<code>@BeforeEach</code> 方法无法直接通过 <code>TestInfo</code> 获取当前测试方法的自定义注解,因为 <code>TestInfo</code> 只提供测试方法名、显示名等元信息,不包含反射所需的 <code>Method</code> 对象。但可以通过 <code>ExtensionContext</code> 获取当前执行的测试方法并完成反射。</p>
<H3>使用 ExtensionContext 获取当前 Method 对象</H3>
<p><code>@BeforeEach</code> 支持注入 <code>ExtensionContext</code>(比 <code>TestInfo</code> 更底层),从中可获取正在执行的测试方法的 <code>Method</code> 实例,进而读取自定义注解:</p>
<ul>
<li>在 <code>@BeforeEach</code> 方法参数中声明 <code>ExtensionContext</code></li>
<li>调用 <code>context.getRequiredTestMethod()</code> 获取 <code>Method</code></li>
<li>用 <code>method.getAnnotation(YourCustomAnnotation.class)</code> 获取注解实例</li>
</ul>
<H3>确保自定义注解保留到运行时</H3>
<p>自定义注解必须添加 <code>@Retention(RetentionPolicy.RUNTIME)</code>,否则反射无法读取:</p>
<pre><code>@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyTag {
String value() default "";
}</code></pre>
<H3>完整示例代码</H3>
<p>假设你有如下注解和测试类:</p>
<pre><code>@MyTag("smoke")
@Test
void testLogin() {
// ...
}
@BeforeEach
void setUp(ExtensionContext context) {
Method method = context.getRequiredTestMethod();
MyTag tag = method.getAnnotation(MyTag.class);
if (tag != null) {
System.out.println("当前测试标记: " + tag.value()); // 输出 "smoke"
}
}</code></pre>
<H3>注意点</H3>
<p>常见问题与规避方式:</p>
<ul>
<li><code>context.getRequiredTestMethod()</code> 在非方法级执行上下文(如容器级)会抛异常,确保只在方法级测试中使用</li>
<li>若测试是嵌套类中的方法,<code>getRequiredTestMethod()</code> 仍能正确返回对应 <code>Method</code></li>
<li>不要尝试从 <code>TestInfo</code> 强转或反射获取 <code>Method</code>——它没有暴露该能力</li>
</ul>