类之前的 Junit(非静态)

发布于 2024-09-01 06:01:10 字数 295 浏览 3 评论 0原文

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

就像非静态函数上的 @BeforeClass 一样?

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

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

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

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

like @BeforeClass on non static function?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

一百个冬季 2024-09-08 06:01:10

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

        }
    }

 ...

A simple if statement seems to work pretty well too:

@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;

        }
    }

 ...
月下客 2024-09-08 06:01:10

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

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

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

如果您使用 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

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.

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

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

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

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

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

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

眼泪淡了忧伤 2024-09-08 06:01:10

如果您不想为一次性初始化设置静态初始值设定项,并且不特别注重使用 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 分别。

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.

In TestNG, this would be equivalent to:

@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 @Before and @After, you can use @BeforeMethod and @AfterMethod respectively.

撩发小公举 2024-09-08 06:01:10

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

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

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/

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

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

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

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://bitbucket.org/radistao/before-after-spring-test-runner/

The only limitation: works only for Spring testing.

(I'm the developer of this testing library)

旧伤还要旧人安 2024-09-08 06:01:10

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

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

朦胧时间 2024-09-08 06:01:10

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

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

The article discuss 2 very nice solutions for this problem:

  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.
書生途 2024-09-08 06:01:10

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


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

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

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't work.)


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:

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

玩心态 2024-09-08 06:01:10

只需使用@BeforeClass:

@BeforeClass
public static void init() {
}

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

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

Just use @BeforeClass:

@BeforeClass
public static void init() {
}

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

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 init method will be called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文