目錄
- 目錄
- 設定注解的屬性
- 執行個體
- 定義
- 使用
- 個人遇到的使用場景
- 場景導入
- 執行個體
- 代碼位址
- 引用
- 系列導航
設定注解的屬性
這種使用場景比較少,但是不失為一種對于注解的深入了解。
執行個體
定義
- Tag.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.LOCAL_VARIABLE})
public @interface Tag {
/**
* tag 标簽
*
* @return tag
*/
String value() default "";
}
使用
- SetValue.java
設定注解的屬性
import com.ryo.jdk.annotation.define.Tag;
import org.junit.Assert;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
public class SetValue {
/**
* 在每一個類執行之前,設定注解的屬性
* @throws NoSuchFieldException if any
* @throws IllegalAccessException if any
*/
@SuppressWarnings("unchecked")
public static void beforeClass() throws NoSuchFieldException, IllegalAccessException {
Method[] methods = SetValue.class.getDeclaredMethods();
for(Method method : methods) {
Tag tag = method.getAnnotation(Tag.class);
if(tag != null) {
InvocationHandler h = Proxy.getInvocationHandler(tag);
Field hField = h.getClass().getDeclaredField("memberValues");
hField.setAccessible(true);
Map memberMethods = (Map) hField.get(h);
memberMethods.put("value", "setAnnotation");
String value = tag.value();
Assert.assertEquals("setAnnotation", value);
}
}
}
@Tag
public void tag() {
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
beforeClass();
}
}
個人遇到的使用場景
場景導入
TestNG 中的
@DataProvider
注解,擁有 dataProvider() 屬性用來指定資料源。
編寫的架構中 dataProvider() 值可以指向固定的值,但是 TestNG 會通過這個屬性來進行值的注入和執行。
- @DataProvider 的屬性
編寫的架構通過注解去解析對應的配置檔案,導緻所有的 @DataProvider 的 dataProvider() 可以使固定的。
但是 TestNG 通過判斷 dataProvider() 是否有值,來進行參數化測試。
是以,這是一個固定的屬性值,使用同一的屬性設定,可以使得使用者代碼變得更加優雅。
執行個體
- TestNgDataProviderTest.java
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
public class TestNgDataProviderTest {
/**
* 是否為空資料準備
* @return 資料
*/
@DataProvider(name = "TestDataProvider")
public Object[][] isEmptyDataProvider(Method method, ITestContext testContext) {
return new Object[][]{
{"", true},
{null, true},
{" ", true},
{"1", false},
{" 1", false}
};
}
/**
* 在每一個類執行之前,設定注解的屬性
* @throws NoSuchFieldException if any
* @throws IllegalAccessException if any
*/
@BeforeClass
public void beforeClass() throws NoSuchFieldException, IllegalAccessException {
Method[] methods = this.getClass().getDeclaredMethods();
for(Method method : methods) {
Test test = method.getAnnotation(Test.class);
if(test != null) {
InvocationHandler h = Proxy.getInvocationHandler(test);
Field hField = h.getClass().getDeclaredField("memberValues");
hField.setAccessible(true);
Map memberMethods = (Map) hField.get(h);
memberMethods.put("dataProvider", "TestDataProvider");
String value = test.dataProvider();
Assert.assertEquals("TestDataProvider", value);
}
}
}
@Test
public void isEmptyTest(final String string, boolean result) {
System.out.println(string+","+result);
Assert.assertEquals(result, StringUtil.isEmpty(string));
}
}
代碼位址
annotation 定義與解析
引用
通過反射,動态修改注解的某個屬性值
系列導航
系列導航