使用反射+注解實現類似JUnit的效果
作者:
網絡轉載 發(fā)布時間:
[ 2016/5/3 11:32:51 ] 推薦標簽:
單元測試 軟件測試工具
比較特殊的是rate,用于提供一種概率性的運行方式。
3、框架核心代碼
package com.sigh.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by sigh on 2015/6/10.
*/
public class SimulationFacade {
interface RunMethod {
void run();
double getRate();
}
interface ReportMethod {
void report();
}
private static List<Object> classes = null;
private static List<RunMethod> runMethods = null;
private static List<ReportMethod> reportMethods = null;
private final static int MAX_OPERATION_TIMES = 100;
static {
classes = new ArrayList<>();
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("src/spring-config.xml");
Map<String, Object> beanNames = applicationContext.getBeansWithAnnotation(Simulation.class);
for (Object o : beanNames.values()) {
classes.add(o);
}
System.out.println(beanNames);
runMethods = new ArrayList<RunMethod>();
reportMethods = new ArrayList<ReportMethod>();
for (final Object o : classes) {
Method[] methods = o.getClass().getDeclaredMethods();
for (final Method method : methods) {
if (method.isAnnotationPresent(Run.class)) {
runMethods.add(new RunMethod() {
@Override
public void run() {
try {
method.invoke(o);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public double getRate() {
return method.getAnnotation(Run.class).rate();
}
});
} else if (method.isAnnotationPresent(Report.class)) {
reportMethods.add(new ReportMethod() {
@Override
public void report() {
try {
method.invoke(o);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
}
}
}
}
public void run() {
double rate = Math.random();
for (RunMethod method : runMethods) {
if (rate <= method.getRate()) {
method.run();
break;
} else {
rate -= method.getRate();
}
}
}
public void report() {
for (ReportMethod method : reportMethods) {
method.report();
}
}
public static class MulTiThreadSimulation {
private final static int THREAD_NUM = 10;
SimulationFacade simulationFacade = new SimulationFacade();
static AtomicInteger operationTimes = new AtomicInteger(0);
public void run() {
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < THREAD_NUM; i++) {
Thread thread = new Thread(new Runnable() {
@Override public void run() {
while (operationTimes.getAndIncrement() < SimulationFacade.MAX_OPERATION_TIMES) {
try {
//仿真測試
simulationFacade.run();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
threadList.add(thread);
}
for (Thread thread : threadList) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void report() {
simulationFacade.report();
}
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, InstantiationException {
MulTiThreadSimulation mulTiThreadSimulation = new MulTiThreadSimulation();
mulTiThreadSimulation.run();
mulTiThreadSimulation.report();
}
}
基本的思路也相對比較清晰,所以也沒有太多需要解釋的地方。
java的內部類確實有很多很有意思的地方,許多地方現在想來還是有些復雜。估計還需要一段時間來慢慢理解java的內存模型了。