在我的代码中,仅当它在JUnit测试中运行时,才需要进行某些修复。如何确定代码是否在JUnit测试内运行?是否有类似JUnit.isRunning()== true的东西?
在我的代码中,仅当它在JUnit测试中运行时,才需要进行某些修复。如何确定代码是否在JUnit测试内运行?是否有类似JUnit.isRunning()== true的东西?
Answers:
如果要以编程方式决定要运行哪个“配置文件”,则可能是一个好主意。考虑使用Spring Profiles进行配置。在集成测试中,您可能需要针对其他数据库进行测试。
这是经过测试的代码
public static boolean isJUnitTest() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getClassName().startsWith("org.junit.")) {
return true;
}
}
return false;
}
首先,这可能不是一个好主意。您应该对实际的生产代码进行单元测试,而不要稍有不同。
如果确实要执行此操作,则可以查看stacktrace,但是由于无论如何都要为此更改程序,因此最好isUnitTesting
在代码中引入一个新的静态布尔字段,并将JUnit设置为true。把事情简单化。
这个线程上的许多人说,在JUnit下运行稍微不同的代码是一个坏主意。我普遍同意,但我认为也有一些例外。
例如,我目前正在为连接到数据库的应用程序编写INTEGRATION(相对于Unit)测试。
这些验收测试通常需要使用特定的测试数据完全重新初始化数据库。
显然,我不希望在实际的生产数据库上进行此操作,因为这可能会完全删除有价值的生产数据。
确保这种情况永远不会发生的最简单方法是,使代码无法在JUnit下运行时连接到生产数据库。反过来,例如,如果生成连接的Factory可以告诉它正在JUnit下运行,并且在这种情况下,除非我们尝试连接的数据库具有已知的名称,它将返回空连接,则可以执行此操作成为测试数据库(例如:“ testdatabase”)。
我可以找到一个理由,那就是当您想在生产类中提供代码以帮助测试时。这将类似于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 = ...
}
如果您由于进行单元测试而做事有所不同,那么您就无法达到单元测试的目的。单元测试应该表现得与生产完全相同(除了设置和拆卸任何必要的数据以及您需要的数据……,但这包含在JUnit测试本身中,而不是您的代码中)。
但是,如果您确实有充分的理由这样做,那么我将看一下堆栈,看看是否有JUnit。
这对我有用:
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中使用。例如:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
最短的(最少的代码)解决方案是在测试未运行时设置一个全局标志。然后,您可以在main()
(或类似的入口点)设置一次,而不必在所有测试类的设置方法中重复设置。只要没有其他输入代码的方法(没有替代方法main
),它就可以工作。
第二个最短的解决方案是像Janning的answer一样扫描调用堆栈中的junit软件包。只要junit不会将自己隐藏在另一个库和一个执行程序的后面,这将起作用。
依赖注入也将起作用,但是在这种情况下,这只是设置本质上是全局标志的一种好方法。
这与用户问题并不严格相关,但是我很确定到达那里的人可能会觉得有用。
我使用以下方法:公开将在测试中使用的程序包本地构造函数。
例如
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);
}
}
在测试中对其进行扩展,并为包本地或受保护的包提供公共构造函数。
在将使用程序包本地构造函数创建该程序包的同一程序包中(在测试中)创建一个公共工厂方法。