Search code examples
javajunitjunit4junit3

setUp/tearDown (@Before/@After) why we need them in JUnit?


I believe that we are all know that setUp (@Before) will execute before any test method and tearDown(@After) will execute after test method.

Also we know that Junit will create one instance of Test per test method.

my question is that can we just move setUp method content to class Constructor and remove setUp method? is there any specific reason to keep setUp method?


Solution

  • This (old) JUnit best practices article puts it like this:

    Do not use the test-case constructor to set up a test case

    Setting up a test case in the constructor is not a good idea. Consider:

    public class SomeTest extends TestCase
       public SomeTest (String testName) {
          super (testName);
          // Perform test set-up
       }
    }
    

    Imagine that while performing the setup, the setup code throws an IllegalStateException. In response, JUnit would throw an AssertionFailedError, indicating that the test case could not be instantiated. Here is an example of the resulting stack trace:

    junit.framework.AssertionFailedError: Cannot instantiate test case: test1   
        at junit.framework.Assert.fail(Assert.java:143)
        at junit.framework.TestSuite.runTest(TestSuite.java:178)
        at junit.framework.TestCase.runBare(TestCase.java:129)
        at junit.framework.TestResult.protect(TestResult.java:100)
        at junit.framework.TestResult.runProtected(TestResult.java:117)
        at junit.framework.TestResult.run(TestResult.java:103)
        at junit.framework.TestCase.run(TestCase.java:120)
        at junit.framework.TestSuite.run(TestSuite.java, Compiled Code)
        at junit.ui.TestRunner2.run(TestRunner.java:429)
    

    This stack trace proves rather uninformative; it only indicates that the test case could not be instantiated. It doesn't detail the original error's location or place of origin. This lack of information makes it hard to deduce the exception's underlying cause.

    Instead of setting up the data in the constructor, perform test setup by overriding setUp(). Any exception thrown within setUp() is reported correctly. Compare this stack trace with the previous example:

    java.lang.IllegalStateException: Oops
        at bp.DTC.setUp(DTC.java:34) 
        at junit.framework.TestCase.runBare(TestCase.java:127)
        at junit.framework.TestResult.protect(TestResult.java:100)
        at junit.framework.TestResult.runProtected(TestResult.java:117)
        at junit.framework.TestResult.run(TestResult.java:103)
        ...
    

    This stack trace is much more informative; it shows which exception was thrown (IllegalStateException) and from where. That makes it far easier to explain the test setup's failure.