java-如何确定代码是否在JUnit测试内运行?
在我的代码中,仅当它在JUnit测试中运行时,才需要进行某些修复。 如何确定代码是否在JUnit测试中运行? 是否有类似JUnit.isRunning()== true的东西?
Dr. Max Völkel asked 2019-11-19T02:27:36Z
11个解决方案
51 votes
如果要以编程方式确定要运行哪个“配置文件”,则可能是一个好主意。 考虑使用Spring Profiles进行配置。 在集成测试中,您可能需要针对其他数据库进行测试。
这是经过测试的有效代码
public static boolean isJUnitTest() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
List list = Arrays.asList(stackTrace);
for (StackTraceElement element : list) {
if (element.getClassName().startsWith("org.junit.")) {
return true;
}
}
return false;
}
Janning answered 2019-11-19T02:27:54Z
25 votes
首先,这可能不是一个好主意。 您应该对实际的生产代码进行单元测试,而不要稍有不同。
如果确实要执行此操作,则可以查看stacktrace,但是由于无论如何都在为此更改程序,因此不妨在代码中引入一个新的静态布尔字段isUnitTesting,并将JUnit设置为true。 把事情简单化。
Thilo answered 2019-11-19T02:28:25Z
16 votes
这个线程上的很多人说,在JUnit下运行稍微不同的代码是一个坏主意。 我普遍同意,但我认为也有一些例外。
例如,我目前正在为连接到数据库的应用程序编写INTEGRATION(相对于Unit)测试。
这些验收测试通常需要使用特定的测试数据完全重新初始化数据库。
显然,我不希望在实际的生产数据库上进行此操作,因为这可能会完全删除有价值的生产数据。
确保这种情况永远不会发生的最简单方法是,使代码无法在JUnit下运行时连接到生产数据库。 反过来,例如,如果生成连接的Factory可以告诉它正在JUnit下运行,并且在这种情况下,除非我们尝试连接的数据库具有已知的名称,它将返回空连接,则可以执行此操作 成为测试数据库(例如:“ testdatabase”)。
user3022950 answered 2019-11-19T02:29:16Z
10 votes
我可以找到一个理由,那就是当您想在生产类中提供代码以帮助测试时。 这将与Java断言类似,后者仅在设置了调试标志时才适用。
像这样的东西:
Object debugState() {
// This is only meant to be called when testing
if (!JUnit.isRunning()) {
throw new IllegalStateException("Not in a test!");
}
// Now compute possibly costly debug information
// not to be used in production
Object state = ...
}
Jaime Saiz answered 2019-11-19T02:29:42Z
4 votes
如果您由于进行单元测试而做事有所不同,那么您就无法达到单元测试的目的。 单元测试应该表现得与生产完全相同(除了设置和拆卸任何必要的数据以及您所需要的数据……但是,这包含在JUnit测试本身中,而不是您的代码中)。
但是,如果您确实有这样做的充分理由,那么我将看一下堆栈,看看是否有JUnit。
SOA Nerd answered 2019-11-19T02:30:13Z
4 votes
如何检查junit jar是否在类路径中?
Snickers3192 answered 2019-11-19T02:30:37Z
2 votes
使用Spring时,可以定义一个保存该值的bean。
在应用程序上下文中:
@Bean
public boolean isRunningTests() {
return false;
}
在测试应用程序上下文中:
@Bean
public boolean isRunningTests() {
return true;
}
将值注入到Spring组件中:
@Resource
private boolean isRunningTests;
private void someMethod() {
if (isRunningTests()) {
....
Milanka answered 2019-11-19T02:31:21Z
0 votes
为了区分测试和不测试,您始终可以在application-test.properties中定义特殊属性或值。
Meir G. answered 2019-11-19T02:31:44Z
0 votes
最短的(最少的代码)解决方案是在测试未运行时设置一个全局标志。 然后,您可以在main()(或类似的入口点)中设置一次,而不必在所有测试类的设置方法中重复设置。 只要没有其他方法可以输入代码(没有替代的main),此方法就会起作用。
第二种最短的解决方案是像Janning的答案一样扫描调用堆栈中的junit软件包。 只要junit不会将自己隐藏在另一个库和一个执行程序的后面,这将起作用。
依赖注入也将起作用,但是在这种情况下,这只是设置本质上是全局标志的一种好方法。
Robert Važan answered 2019-11-19T02:32:23Z
0 votes
这对我有用:
private Boolean isRunningTest = null;
private boolean isRunningTest() {
if (isRunningTest == null) {
isRunningTest = true;
try {
Class.forName("org.junit.Test");
} catch (ClassNotFoundException e) {
isRunningTest = false;
}
}
return isRunningTest;
}
只要将junit作为范围“ test”的依赖项包括在内,它就可以在Maven测试以及Eclipse IDE内部使用。例如:
junit
junit
${junit.version}
test
Andrea M answered 2019-11-19T02:32:53Z
-1 votes
这与用户问题并不严格相关,但是我很确定到达那里的人可能会发现它有用。
我使用以下方法:公开将在测试中使用的程序包本地构造函数。
例如
src / main / java / ApplicationService.java
public class ApplicationService {
private final Integer someInternalObject;
public ApplicationService(String somePublicArgument) throws NumberFormatException {
someInternalObject = Integer.valueOf(somePublicArgument, 16);
}
ApplicationService(Integer someInternalObject) {
this.someInternalObject = someInternalObject;
}
}
src / test / ApplicationServiceTest.Java
public class ApplicationServiceTest {
@Test
public void testSomething() throws Exception {
ApplicationService applicationService = new ApplicationService(0);
}
}
暴露给所有测试
不是期末班
在测试中扩展它,并为包本地或受保护的程序包提供公共构造函数。
期末课程
在将使用本地程序包构造函数创建该程序包的同一程序包中(在测试中)创建一个公共工厂方法。
tux_mind answered 2019-11-19T02:34:11Z