课前的Junit(非静态)

时间:2010-05-13 09:22:10

标签: java junit

是否有任何最佳实践可以让Junit在测试文件中执行一次函数,它也不应该是静态的。

类似非静态函数的@BeforeClass

这是一个丑陋的解决方案:

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

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

8 个答案:

答案 0 :(得分:34)

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

但它并不是所有继承的最佳选择。这就是JUnit 4使用注释的原因。

另一个选择是在factory / util类中创建一个helper方法,让该方法完成工作。

如果您使用的是Spring,则应考虑使用@TestExecutionListeners注释。 像这样的测试:

@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 */
}

注意:添加自定义DependencyInjectionTestExecutionListener时,请勿忽略/错过TestExecutionListeners。如果您这样做,所有的自动装置都将是null

答案 1 :(得分:34)

简单的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;

        }
    }

 ...

答案 2 :(得分:18)

如果您不想为一次初始化设置静态初始值设定项,而不是特别关于使用JUnit,请查看TestNG。 TestNG支持使用各种配置选项的非静态一次性初始化,所有这些都使用注释。

在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

答案 3 :(得分:7)

轻松使用Runnable / @BeforeAllMethods注释在实例上下文(非静态)中运行方法,其中所有注入的值都可用。

有一个特殊的测试库:

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/

唯一限制:仅适用于 Spring 测试。

(我是这个测试库的开发者)

答案 4 :(得分:0)

我从未尝试过,但也许你可以创建一个无参数的构造函数并从那里调用你的函数?

答案 5 :(得分:0)

更新:请参阅Cherry的评论,了解以下建议存在缺陷的原因。(我在这里保留答案而不是删除,因为评论可能会向其他人提供有用的信息,说明为什么会这样做< strong>不工作。)


如果使用依赖注入(例如Spring),另一个值得考虑的选择是@PostConstruct。这将保证依赖注入完成,这在构造函数中不是这样的:

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

<击>

答案 6 :(得分:0)

The article讨论了这个问题的2个非常好的解决方案:

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

答案 7 :(得分:0)

只需使用@BeforeClass

@BeforeClass
public static void init() {
}

init非静态是没有意义的,因为每个测试都在一个单独的实例中运行。实例 运行init与任何测试的实例都不匹配。

您可能希望它是非静态的唯一原因是在子类中覆盖它,但您可以这样做 用静态方法也是如此。只需使用相同的名称,只会调用子类init方法。