在我的代码中,我需要在JUnit测试中运行时才进行某些修复。如何判断代码是否在JUnit测试中运行?有没有类似JUnit.isRunning()== true的东西?
答案 0 :(得分:46)
如果您想以编程方式决定运行哪个“配置文件”,这可能是个好主意。想一想Spring Profiles的配置。在集成测试中,您可能希望针对不同的数据库进行测试。
这是经过测试的代码
public static boolean isJUnitTest() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
List<StackTraceElement> list = Arrays.asList(stackTrace);
for (StackTraceElement element : list) {
if (element.getClassName().startsWith("org.junit.")) {
return true;
}
}
return false;
}
答案 1 :(得分:23)
首先,这可能不是一个好主意。您应该对实际生产代码进行单元测试,而不是稍微不同的代码。
如果你真的想这样做,你可以查看堆栈跟踪,但是既然你正在改变你的程序,你也可以在你的代码中引入一个新的静态布尔字段isUnitTesting
,让JUnit将此设置为true。保持简单。
答案 2 :(得分:16)
在这个帖子上有很多人说,在JUnit下,代码运行方式略有不同是个坏主意。我普遍同意,但我认为有一些例外。
例如,我目前正在为连接到数据库的应用程序编写INTEGRATION(而不是Unit)测试。
这些验收测试通常需要使用特定的测试数据完全重新初始化DB。
显然,我不希望这样,甚至不能在实际的生产数据库上完成,因为这可能会完全抹掉有价值的生产数据。
保证永远不会发生这种情况的最简单方法是使代码在JUnit下运行时无法连接到生产数据库。例如,如果生成连接的Factory可以告诉它在JUnit下运行,那么这反过来就可以完成,在这种情况下,除非我们尝试连接的数据库具有已知的名称,否则将返回空连接成为测试数据库(例如:“testdatabase”)。
答案 3 :(得分:10)
我可以为此找到理由,当您想要在生产类中提供代码以帮助测试时。这类似于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 = ...
}
答案 4 :(得分:4)
如果你做的事情不同,因为你正在进行单元测试,那么你就会失去单元测试的目的。单元测试应该完全像生产一样执行(除了设置和拆除任何必要的数据之外,你需要......但是它包含在JUnit测试本身而不是你的代码中)。
但是,如果你确实有充分的理由,我会查看堆栈,看看是否有JUnit。
答案 5 :(得分:4)
检查junit jar是否在类路径中怎么样?
答案 6 :(得分:2)
使用Spring时,可以定义一个保存该值的bean。
在应用程序上下文中:
@Bean
public boolean isRunningTests() {
return true;
}
在测试应用程序上下文中:
@Resource
private boolean isRunningTests;
private void someMethod() {
if (isRunningTests()) {
....
将值注入Spring组件:
{{1}}
答案 7 :(得分:0)
为了区分test和no test,你总是可以在application-test.properties中定义特殊属性或值。
答案 8 :(得分:0)
最短(最少代码)解决方案是在测试不运行时设置全局标志。然后,您可以在main()
(或类似的入口点)中设置一次,而不是在所有测试类的设置方法中重复设置它。只要没有其他方式输入代码(无替代main
),这将有效。
第二个最短的解决方案是扫描调用堆栈中的junit包,如Janning's answer中所示。这将是有效的,因为junit不会隐藏在另一个库和执行者之后。
依赖注入也会起作用,但在这种情况下,它只是一种奇特的方式来设置本质上是一个全局标志。
答案 9 :(得分:0)
这对我有用:
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;
}
它可以用于Maven测试以及Eclipse IDE内部,只要将junit作为范围“ test”的依赖项包括在内,例如:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
答案 10 :(得分:-1)
这与用户问题并不严格相关,但我非常确定那些到达那里的人可能会觉得它很有用。
我使用以下方法:公开将在测试中使用的包本地构造函数。
e.g。
的src /主/爪哇/ 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 /测试/ ApplicationServiceTest.Java
public class ApplicationServiceTest {
@Test
public void testSomething() throws Exception {
ApplicationService applicationService = new ApplicationService(0);
}
}
在测试中扩展它,并为包本地或受保护的包提供公共构造函数。
在同一个包中(在测试中)使用package-local构造函数创建一个公共Factory Method。