Java Junit 课前(非静态)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2825615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:18:28  来源:igfitidea点击:

Junit before class ( non static )

javajunit

提问by Roman

Are there any best practices to get Junit execute a function once in a test file , and it should also not be static.

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

like @BeforeClasson non static function?

喜欢@BeforeClass非静态函数?

Here is an ugly solution :

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

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

well this is something i dont want to do , and i am looking for an integrated junit solution.

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

采纳答案by Kartik

If you don't want to set up static initializers for one time initialization and are not particular about using JUnit, take a look at TestNG. TestNG supports non-static, one-time initialization with a variety of configuration options, all using annotations.

如果你不想设置静态初始化器一次性初始化并且对使用JUnit不讲究,可以看看TestNG。TestNG 支持非静态、一次性初始化,具有多种配置选项,全部使用注解。

In TestNG, this would be equivalent to:

在 TestNG 中,这相当于:

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

For teardown,

对于拆解,

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

For the TestNG equivalent of JUnit 4's @Beforeand @After, you can use @BeforeMethodand @AfterMethodrespectively.

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

回答by Roman

I've never tried but maybe you can create a no-argument constructor and call you function from there?

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

回答by Espen

To use an empty constructor is the easiest solution. You can still override the constructor in the extended class.

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

But it's not optimal with all the inheritance. That's why JUnit 4 uses annotations instead.

但是对于所有的继承来说,它并不是最优的。这就是 JUnit 4 使用注释的原因。

Another option is to create a helper method in a factory/util class and let that method do the work.

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

If you're using Spring, you should consider using the @TestExecutionListenersannotation. Something like this test:

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

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

Spring's AbstractTestExecutionListenercontains for example this empty method that you can override:

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

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

NOTE:DO NOT overlook/miss DependencyInjectionTestExecutionListenerwhile adding custom TestExecutionListeners. If you do, all the autowires will be null.

注意:不要忽视/小姐DependencyInjectionTestExecutionListener,同时添加自定义TestExecutionListeners。如果你这样做,所有的自动装配将是null.

回答by Upgradingdave

A simple if statement seems to work pretty well too:

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

        }
    }

 ...

回答by Steve Chambers

UPDATE: Please see the comment by Cherry for why the suggestion below is flawed.(Am keeping the answer on here rather than deleting as the comment may provide useful information to others as to why this doesn'twork.)

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



Another option worth considering if using dependency injection (e.g. Spring) is @PostConstruct. This will guarantee dependency injection is complete, which wouldn't be the case in a constructor:

如果使用依赖注入(例如 Spring),另一个值得考虑的选项是@PostConstruct. 这将保证依赖注入是完整的,在构造函数中不会出现这种情况:

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

回答by kedzi

The articlediscuss 2 very nice solutions for this problem:

这篇文章讨论了这个问题的 2 个非常好的解决方案:

  1. "clean" junit with custom Runner (using interface but you could extend it with a custom annotation e.g. @BeforeInstance)
  2. Spring execution listeners as mentioned by Espen before.
  1. 带有自定义 Runner 的“清理”junit(使用接口,但您可以使用自定义注释对其进行扩展,例如 @BeforeInstance)
  2. Espen 之前提到的 Spring 执行侦听器。

回答by fgb

Just use @BeforeClass:

只需使用@BeforeClass

@BeforeClass
public static void init() {
}

It doesn't make sense for initto be non-static because each test is run in a separate instance. The instance that initis run on would not match the instance of any test.

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

The only reason that you might want it to be non-static is to override it in subclasses, but you can do this with static methods too. Just use the same name, and only the subclass initmethod will be called.

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

回答by radistao

Easily use @BeforeAllMethods/@AfterAllMethodsannotations to run a method inside the instance context (non-static), where all injected values will be available.

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

There is a special testing library for this:

为此有一个特殊的测试库:

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

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/

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

The only limitation: works only for Springtesting.

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

(I'm the developer of this testing library)

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