@BeforeClass: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(9 intermediate revisions by the same user not shown)
Line 2: Line 2:


* [[JUnit#Annotations|JUnit]]
* [[JUnit#Annotations|JUnit]]
* [[@AfterClass]]


=Overview=
=Overview=


The annotation must be attached to a '''static''' method.
The annotation must be attached to a '''static''' method.
=<tt>@BeforeClass</tt> and Class Hierarchies=


If two methods '''with different names''' are annotated with <code>@BeforeClass</code> in a test class hierarchy, as shown below:
If two methods '''with different names''' are annotated with <code>@BeforeClass</code> in a test class hierarchy, as shown below:
Line 12: Line 15:
  TestBase.java
  TestBase.java
   │  @BeforeClass
   │  @BeforeClass
   │  public static void methodA() {
   │  public static void testBaseOneTimeSetup() {
   │    ...
   │    ...
   │  }
   │  }
Line 18: Line 21:
   └── SomeTest.java
   └── SomeTest.java
         @BeforeClass
         @BeforeClass
         public static void methodB() {
         public static void someTestOneTimeSetup() {
           ...
           ...
         }
         }
</font>
</font>
then both methods are executed only once, in this order: first the parent class method, then the subclass method (<code>methodA()</code> <code>methodB()</code>). The rule holds true in a multi-layer hierarchy.
then both methods are executed only once, in this order: first the parent class method (<code>testBaseOneTimeSetup()</code>), then the subclass method (<code>someTestOneTimeSetup()</code>). The rule holds true in a multi-layer hierarchy.


However, if both methods '''have the same name''', an override of sorts takes place and only the method belonging to the subclass is executed:
However, if both methods '''have the same name''', an override of sorts takes place and only the method belonging to the subclass is executed:
Line 28: Line 31:
  TestBase.java
  TestBase.java
   │  @BeforeClass
   │  @BeforeClass
   │  public static void someMethod() {
   │  public static void oneTimeClassSetup() {
   │    ...
   │    ...
   │  }
   │  }
Line 34: Line 37:
   └── SomeTest.java
   └── SomeTest.java
         @BeforeClass
         @BeforeClass
         public static void someMethod() {
         public static void oneTimeClassSetup() {
           ...
           ...
         }
         }
</font>
</font>
Only <code>SomeTest.someMethod()</code> is executed, so if you need the logic executed in superclass, it must be invoked explicitly with:
Only <code>SomeTest.oneTimeClassSetup()</code> (the most specific subclass) is executed, so if you need the logic executed in superclass, it must be invoked explicitly with:
<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
class SomeTest {
class SomeTest {
   @BeforeClass
   @BeforeClass
   public static void someMethod() {
   public static void oneTimeClassSetup() {
     TestBase.someMethod();
     TestBase.oneTimeClassSetup();
   }
   }
}
}
</syntaxhighlight>
This behavior is useful when we want to customize static fields in subclass, then execute the <code>@BeforeClass</code> superclass behavior.
In conclusion, if class-level one-time initialization is needed for each level of a class hierarchy, the best solution is to name <code>@BeforeClass</code> methods differently for each class. This way, all methods are executed in order, starting from the root of the hierarchy and continuing towards the bottom, ending with the most specific subclass. If customization of static fields is required in subclass, annotated same-name methods with <code>@BeforeClass</code> both in superclass and subclass.
Recommended naming convention:
<syntaxhighlight lang='java'>
<syntaxhighlight lang='java'>
class SomeTest {
  @BeforeClass
  public static void someTestOneTimeSetup() {
    ...
  }
}
</syntaxhighlight>

Latest revision as of 23:11, 31 August 2021

Internal

Overview

The annotation must be attached to a static method.

@BeforeClass and Class Hierarchies

If two methods with different names are annotated with @BeforeClass in a test class hierarchy, as shown below:

TestBase.java
  │  @BeforeClass
  │  public static void testBaseOneTimeSetup() {
  │     ...
  │  }
  │
  └── SomeTest.java
        @BeforeClass
        public static void someTestOneTimeSetup() {
          ...
        }

then both methods are executed only once, in this order: first the parent class method (testBaseOneTimeSetup()), then the subclass method (someTestOneTimeSetup()). The rule holds true in a multi-layer hierarchy.

However, if both methods have the same name, an override of sorts takes place and only the method belonging to the subclass is executed:

TestBase.java
  │  @BeforeClass
  │  public static void oneTimeClassSetup() {
  │     ...
  │  }
  │
  └── SomeTest.java
        @BeforeClass
        public static void oneTimeClassSetup() {
          ...
        }

Only SomeTest.oneTimeClassSetup() (the most specific subclass) is executed, so if you need the logic executed in superclass, it must be invoked explicitly with:

class SomeTest {
  @BeforeClass
  public static void oneTimeClassSetup() {
     TestBase.oneTimeClassSetup();
  }
}

This behavior is useful when we want to customize static fields in subclass, then execute the @BeforeClass superclass behavior.

In conclusion, if class-level one-time initialization is needed for each level of a class hierarchy, the best solution is to name @BeforeClass methods differently for each class. This way, all methods are executed in order, starting from the root of the hierarchy and continuing towards the bottom, ending with the most specific subclass. If customization of static fields is required in subclass, annotated same-name methods with @BeforeClass both in superclass and subclass. Recommended naming convention:

class SomeTest {
  @BeforeClass
  public static void someTestOneTimeSetup() {
     ...
  }
}