JUnit: using constructor instead of @Before

I am using JUnit 4. I do not see the difference between initializing in the constructor or using the dedicated init function annotated by @Before . Does this mean that I do not need to worry about it?

Is there a case where @Before provides more than just initialization in the constructor?

+50
constructor initialization junit
May 23 '11 at 7:22
source share
8 answers

No, using a constructor to initialize your JUnit test device is technically equal to the @Before method (due to the fact that JUnit creates a new instance of the test class for each @Test ). The only (connotational) difference is that it breaks the symmetry between @Before and @After , which can be confusing for some. IMHO it is better to adhere to conventions (using @Before ).

Note also that prior to JUnit 4 and annotations, the setUp() and tearDown() methods were allocated - the @Before and @After replace them, but retain the main logic. Thus, using annotations also makes life easier for someone migrating from JUnit 3 or earlier.

+61
May 23 '11 at 7:30 a.m.
source share

@ First of all, it makes sense to use it in some cases, because it gets the name AFTER the constructor for the class. This difference is important when you use a mock structure like Mockito with @Mock annotations because your @Before method will be called after mocks is initialized. You can then use your mocks to provide constructor arguments for the class you are testing.

I find this to be a very common pattern in my unit tests when using beans collaboration.

Here is an example (admittedly far-fetched):

 @RunWith(MockitoJUnitRunner.class) public class CalculatorTest { @Mock Adder adder; @Mock Subtractor subtractor; @Mock Divider divider; @Mock Multiplier multiplier; Calculator calculator; @Before public void setUp() { calculator = new Calculator(adder,subtractor,divider,multiplier); } @Test public void testAdd() { BigDecimal value = calculator.add(2,2); verify(adder).add(eq(2),eq(2)); } } 
+20
Sep 10 '12 at 19:24
source share

I prefer to declare my fixes as final and initialize them inline or in the constructor, so I remember to initialize them! However, since the exceptions thrown at @Before are handled in a more user-friendly way, I usually initialize the test object in @Before.

+5
Aug 11 '11 at 12:01
source share

I prefer to use constructors to initialize my test objects, because it allows me to make all the final members so that the IDE or the compiler tells me when the constructor forgot to initialize the element and does not allow another method to set them.

IMHO, @Before violates one of the most important Java conventions - rely on the constructor to fully initialize the objects!

+5
Oct 02 '14 at 20:49
source share

@Before is called before any @Test more than once per test class.
This can be used for reset / init data for each specific test (for example, to reset variables to a specific value, etc.).

In the same mod, @After can be used to clear code after executing the @Test method.

See: http://junit.sourceforge.net/javadoc/org/junit/Before.html

+2
May 23 '11 at 7:30 a.m.
source share

@Before makes sense to use for several reasons. This makes your test code more readable. It corresponds to the @After annotation, which is responsible for the release of used resources and is analogous to the @BeforeClass annotation.

0
May 23 '11 at 7:30 a.m.
source share

There is no difference except that the constructor is the only method that can initialize @Rule objects:

 public class TestClass { @Rule public SomeRule rule; public TestClass() { // code to initialize the rule field conf = new RuleConf() rule = new SomeRule(conf) } } 
0
Nov 20 '16 at 8:45
source share

There is one thing that a constructor can archive, but not @Before.

You should use the constructor when you need to set the initial fields defined in the parent class. For example:

 abstract class AbstractIT { int fieldAssignedInSubClass; public AbstractIT(int fieldAssignedInSubClass) { this.fieldAssignedInSubClass= fieldAssignedInSubClass; } @Before void before() { // comsume fieldAssignedInSubClass } } public class ChildIT extends AbstractIT{ public ChildIT() { // assign fieldAssignedInSubClass by constructor super(5566); } @Before void before() { // you cannot assign fieldAssignedInSubClass by a @Before method } } 
0
Dec 27 '17 at 7:39 on
source share



All Articles