简体   繁体   English

使用@BeforeClass和在JUnit 4 Java中使用实例或静态变量有什么区别?

[英]What's the difference between using @BeforeClass and using instance or static variable in JUnit 4 Java?

I'm new to unit test. 我是单元测试的新手。 About the purpose of using @Before annotation in JUnit 4 . 关于在JUnit 4中使用@Before注释的目的。 I just don't know the point of using it: 我只是不知道使用它的意义:

public class FoodTestCase {
    static private Food sandwich;

    @BeforeClass
    public static void initialise(){
        sandwich = new Sandwich();    
    }

}

vs VS

public class FoodTestCase {
    static private Food sandwich = new Sandwich();

}

What's the difference? 有什么不同?

In this case it may not be necessary, as the initialization is really simple. 在这种情况下,可能没有必要,因为初始化非常简单。

In case you have some logging, complex initialization or need to free some resources, you have to use @BeforeClass and @AfterClass 如果你有一些日志记录,复杂的初始化或需要释放一些资源,你必须使用@BeforeClass@AfterClass

Almost no difference. 几乎没有区别。 But if constructor of Sandwich throws exception you cannot initialize it directly static private Food sandwich = new Sandwich(); 但是如果Sandwich构造函数抛出异常,则无法直接初始化它static private Food sandwich = new Sandwich(); but have to wrap initialization with try/catch block. 但必须使用try/catch块进行初始化。 However method initialise() may be declared as throws MyException , so the test case will fail if exception indeed thrown during initialization. 但是,方法initialise()可能被声明为throws MyException ,因此如果在初始化期间确实抛出了异常,则测试用例将失败。

Suppose, you had all of your Food related data (say a Menu) setup at the backend in a database table. 假设您在数据库表的后端设置了所有与食物相关的数据(比如菜单)。 Your Food test cases could then pertain to updating the Menu (all the CRUD ops basically). 您的食物测试案例可能与更新菜单(基本上所有CRUD操作)有关。

Instead of opening a DB connection for every test case (using @Before ); 而不是为每个测试用例打开数据库连接(使用@Before ); it would be wise if you do it just once before you run all your test cases via a method marked @BeforeClass . 如果您在通过标记为@BeforeClass的方法运行所有测试用例之前只执行一次将是明智的。

Now the use of a method makes sense as the setup would most probably be slightly complex (you may decide to use a Spring container to get your Connection from a DataSource ) and you would not be able to achieve it with a single line where you declare your Connection object. 现在使用方法是有意义的,因为设置很可能会稍微复杂一些(您可能决定使用Spring容器从DataSource获取Connection )并且您将无法使用您声明的单行实现它你的Connection对象。

Similarly, you would use the @AfterClass to tear down your global setup (for all the test cases) ie closing your database connection here. 同样,您可以使用@AfterClass拆除全局设置(针对所有测试用例),即在此处关闭数据库连接。

I think the idea is like that: You use @AfterClass to free resources. 我认为这个想法是这样的:你使用@AfterClass来释放资源。 Then it is logical to have @BeforeClass to acquire them. 然后让@BeforeClass获取它们是合乎逻辑的。 Because it may not be a good idea to let developer to guess that he need to use static block. 因为让开发人员猜测他需要使用静态块可能不是一个好主意。

In your particular example - not much. 在你的特定例子中 - 并不多。 However there is also @Before annotation which will run prior to every test in your class. 但是,还有@Before注释将在您班级的每个测试之前运行。 Take a look at http://selftechy.com/2011/05/17/junit4-before-vs-beforeclass-after-vs-afterclass , it is explained well there. 看看http://selftechy.com/2011/05/17/junit4-before-vs-beforeclass-after-vs-afterclass ,它在那里得到了很好的解释。

@BeforeClass is for static initializations. @BeforeClass用于静态初始化。

Instances created here will be reused across all of your @Test s 此处创建的实例将在所有@Test重复使用

Whereas @Before is per @Test . @Before@Test

Usually @BeforeClass is reserved for objects which are relatively expensive to instantiate. 通常@BeforeClass保留用于实例化相对昂贵的对象。
eg Database connections 例如数据库连接

Inheritance adds another wrinkle: 继承增加了另一个皱纹:

Let's say you have two JUnit tests that extend a common base class. 假设您有两个扩展公共基类的JUnit测试。 And let's say the base class has both a static initializer block and a @BeforeClass method. 我们假设基类同时具有静态初始化块 @BeforeClass方法。 In this case, the static initializer block will run once , while the @BeforeClass method will run twice . 在这种情况下,静态初始化程序块将运行一次 ,而@BeforeClass方法将运行两次

So, if you have a very expensive computation or resource that you need set up across a whole suite of test cases that share a common base class, then you could use the static initializer block for that. 因此,如果您需要在一共享公共基类的测试用例中设置非常昂贵的计算或资源,那么您可以使用静态初始化程序块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取jUnit:s @BeforeClass的静态字段 - Get past static field of jUnit:s @BeforeClass “ Factory方法”和“使用New创建实例”之间有什么区别? - What's the difference between “Factory Method” and “using New to create an instance”? 与@TestFactory Stream相比,使用JUnit 5的@ParametrizedTest的优势之间有什么区别? <DynamicTest> ? - What's the difference between / advantage of using JUnit 5's @ParametrizedTest over @TestFactory Stream<DynamicTest>? 在TestExecutionListener类中为BeforeClass junit使用Autowired - Using Autowired in a TestExecutionListener class for BeforeClass junit 将JUnit @BeforeClass与Cucumber一起使用…是否有效? - Using JUnit @BeforeClass with Cucumber…does it work? java / oops中的静态变量和动态变量有什么区别? - What is the difference between a static variable and a dynamic variable in java/oops? 使用套件时,JUnit 4 @BeforeClass和@AfterClass - JUnit 4 @BeforeClass & @AfterClass when using Suites 使用SoapUI和Java代码有什么区别? - What's the difference between using SoapUI and java code? java和PHP之间使用静态的区别? - Difference of using static between java and PHP? JUnit 中的失败和错误有什么区别? - What's the difference between failure and error in JUnit?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM