在项目中编写单元测试类的时候,很多地方需要用到token,而这个token是启动web项目才会生成的。所以为了动态获取token,就编写了一个http工具类来根据写死的url地址注入bean来生成,但是这样就会导致每次启动web项目的时候都会去执行,而我想要的是只在测试的时候去解析。
那怎么办呢?就是根据线程堆栈信息来判断当前是否存在junit这条线程,如果存在,那么再执行解析方法。
public static boolean isRunningTest() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
String stackString = stackTraceElement.toString();
if (stackString.lastIndexOf("junit.runners") > -1) {
return true;
}
}
return false;
}
这里为什么是"junit.runners"呢?
Runner是Junit中的一个抽象类
public abstract class Runner implements Describable {
public Runner() {
}
public abstract Description getDescription();
public abstract void run(RunNotifier var1);
public int testCount() {
return this.getDescription().testCount();
}
}
可以通过@Runwith注解来设置一个Runner要执行的测试。
JUnit测试的启动是通过使用JUnitCore类实现的。也可以通过使用命令行,或者使用JUnitCore各种run()方法中的一个(这种方式就是IDE开发工具在你点击run test按钮的时候做的工作)来启动。比如:
JUnitCore.runClasses(MyTestClass.class);
然后JUnitCore使用反射来为传递的测试类找到一个合适的Runner。其中的一个步骤就是查找测试类上的@RunWith注解。如果没有找到其他的Runner,将使用默认的Runner(BlockJUnit4ClassRunner)。Runner将被实例化,测试类会被传递给Runner。然后Runner就会实例化传进来的测试类,然后运行。
而这个runners便是执行runner的线程。
当然,针对上面的问题还有一个解决办法,就是编写一个类,然后使用@BeforeClass执行前置逻辑以及@AfterClass执行后置逻辑,让测试类继承这个类即可。需要注意的是,使用这两个注解的方法必须声明成public static,原因也很简单,每次执行@Test注解的方法就相当于创建一个实例,而在运行@BeforeClass和@AfterClass注解的方法时,测试类还没有实例化。执行顺序:@BeforeClass>@Before>@Test>@AfterClass>@After