我如何知道代码是否在JUnittesting中运行?
在我的代码中,我只需要在JUnittesting中运行某些修复。 我如何知道代码是否在JUnittesting中运行? 有没有像JUnit.isRunning()== true?
首先,这可能不是一个好主意。 你应该unit testing实际的生产代码,而不是稍微不同的代码。
如果你真的想这样做,你可以看一下isUnitTesting
,不过既然你正在改变你的程序,那么你也可以在你的代码中引入一个新的静态布尔字段isUnitTesting
,并让JUnit将它设置为true。 把事情简单化。
如果您想以编程方式决定要运行哪个“configuration文件”,这可能是一个好主意。 考虑configuration弹簧configuration文件。 在集成testing中,您可能需要针对不同的数据库进行testing。
在这里,它的testing代码工作
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; }
这个线程上有很多人说,在JUnit下,代码的运行方式略有不同。 我普遍同意,但我认为有一些例外。
例如,我正在为连接到数据库的应用程序编写INTEGRATION(而不是Unit)testing。
这些验收testing通常需要用特定的testing数据完全重新初始化数据库。
显然,我不希望这样的EVER,EVER在实际的生产数据库上完成,因为这可能会完全抹去有价值的生产数据。
保证这种情况永远不会发生的最简单的方法就是使代码在JUnit下运行时无法连接到生产数据库。 例如,如果生成连接的Factory可以告诉它在JUnit下运行,并且在这种情况下将返回空连接,除非我们试图连接的数据库具有已知的名称成为testing数据库(例如:“testdatabase”)。
我可以find一个理由,当你想在生产类提供代码来帮助testing。 这与Java断言类似,只有在设置了debugging标志时才适用。
像这样的东西:
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 = ... }
如果你做的事情不同,因为你正在做一个unit testing,那么你就打败了unit testing的目的。 一个unit testing应该像生产一样执行(除了设置和拆卸任何必要的数据,这样你需要….但包含在JUnittesting本身,而不是你的代码)。
然而,如果你真的有一个很好的理由,我会看看堆栈,看看JUnit是否在那里。
如何检查junit jar是否在类path中?
当使用Spring时,可以定义一个拥有这个值的bean。
在应用上下文中:
@Bean public boolean isRunningTests() { return false; }
在testing应用上下文中:
@Bean public boolean isRunningTests() { return true; }
将值注入Spring组件:
@Resource private boolean isRunningTests; private void someMethod() { if (isRunningTests()) { ....
这与用户提出的问题并不严格相关,但是我相当确定那些到达那里的人可能会觉得它有用。
我使用以下方法:公开将从testing中使用的包本地构造函数。
例如
的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 /testing/ ApplicationServiceTest.Java
public class ApplicationServiceTest { @Test public void testSomething() throws Exception { ApplicationService applicationService = new ApplicationService(0); } }
将其暴露给所有testing
不是最后一堂课
将其扩展到testing中,并为本地包或受保护包提供一个公共构造函数。
最后一堂课
在同一个包(在testing中)中创build一个公共的工厂方法 ,它将使用包本地构造函数创build它。
为了区分testing和不testing,你总是可以在application-test.properties中定义特殊的属性或值。
最短的(最less代码)解决scheme是在testing未运行时设置全局标志。 然后,您可以在main()
(或类似的入口点)中设置一次,而不是在所有testing类的设置方法中重复设置它。 只要没有其他方式input代码(无替代main
),这将工作。
第二个最短的解决scheme是像Janning的答案那样扫描junit包的调用堆栈。 只要junit不会把自己隐藏在另一个图书馆和执行者的后面,
dependency injection也可以起作用,但是在这种情况下,这只是一个奇特的方式来设置本质上是一个全球性的旗帜。
我同意以前的答案,在生产代码中混合使用testing代码似乎是个不错的主意。 如果你不能用JUnit和模拟框架来执行你想要的testing,你应该重新考虑你的devise。 良好的嘲讽框架: http : //easymock.org/ http://mockito.org/