上课之前的Junit(非静态)

有没有最好的做法来让Junit在testing文件中执行一次函数,而且它也不应该是静态的。

像非静态函数的@BeforeClass

这是一个丑陋的解决scheme:

 @Before void init(){ if (init.get() == false){ init.set(true); // do once block } } 

以及这是我不想做的事情,我正在寻找一个集成的junit解决scheme。

如果您不想为一次初始化设置静态初始化程序,而不是使用JUnit,请查看TestNG。 TestNG支持使用各种configuration选项的非静态,​​一次性初始化,全部使用注释。

在TestNG中,这将相当于:

 @org.testng.annotations.BeforeClass public void setUpOnce() { // One time initialization. } 

对于拆解,

 @org.testng.annotations.AfterClass public void tearDownOnce() { // One time tear down. } 

对于JUnit 4的@Before@After的TestNG等价物,可以分别使用@BeforeMethod@AfterMethod

使用空的构造函数是最简单的解决scheme。 您仍然可以覆盖扩展类中的构造函数。

但是对于所有的inheritance来说并不是最优的。 这就是为什么JUnit 4使用注释来代替。

另一种方法是在factory / util类中创build一个辅助方法,并让该方法完成工作。

如果你使用Spring,你应该考虑使用@TestExecutionListeners注解。 像这样的testing:

 @RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners({CustomTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) @ContextConfiguration("test-config.xml") public class DemoTest { 

Spring的AbstractTestExecutionListener包含了例如这个你可以覆盖的空方法:

 public void beforeTestClass(TestContext testContext) throws Exception { /* no-op */ } 

一个简单的if语句似乎也工作得很好:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:test-context.xml"}) public class myTest { public static boolean dbInit = false; @Autowired DbUtils dbUtils; @Before public void setUp(){ if(!dbInit){ dbUtils.dropTables(); dbUtils.createTables(); dbInit = true; } } ... 

我从来没有尝试,但也许你可以创build一个无参的构造函数,并从那里调用你的function?

本文讨论了这个问题的两个非常好的解决scheme:

  1. 使用自定义Runner的“clean”junit(使用接口,但可以使用自定义注释来扩展它,例如@BeforeInstance)
  2. Spring之前的Espen提到的执行监听器。

只需使用@BeforeClass

 @BeforeClass public static void init() { } 

init不是非静态的,因为每个testing都在一个单独的实例中运行。 运行init的实例不匹配任何testing的实例。

你可能希望它是非静态的唯一原因是在子类中覆盖它,但你也可以用静态方法来做到这一点。 只要使用相同的名称,只会调用子类的init方法。

更新:请看樱桃评论为什么下面的build议是有缺陷的。 (我现在答案不是删除/编辑,因为评论可能会提供有用的信息,为什么这不起作用)。


另一个值得考虑的select是否使用dependency injection(例如Spring)是@PostConstruct 。 这将保证dependency injection是完整的,在构造函数中不会出现这种情况:

 @PostConstruct public void init() { // One-time initialization... } 

这里有一个专门的testing库:

https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0

https://bitbucket.org/radistao/before-after-spring-test-runner/

可以很容易地使用@BeforeAllMethods / @AfterAllMethods注解在实例上下文(非静态)内运行一个方法,其中所有注入的值都将可用。

唯一的限制:仅适用于Springtesting。

(我是这个testing库的开发者)