Here are 3 good reasons why. In summary:
Some situations may prefer to defer setting up test fixtures as long as possible, to just before the test case executes.
Some test cases may be part of a deep test case inheritance hierarchy. It may be preferable to defer setting up test fixtures until the full hierarchy of constructors has completed.
You get better diagnostics if setup code fails in setUp() rather than if it fails in the constructor.
1. Defer setting up fixtures until just before test case
Design for Usability
http://www.artima.com/weblogs/viewpost.jsp?thread=70189
... And as Elliotte Rusty Harold put it, if you're going to create a new TestCase instance for each test method, "why the hell bother with a setUp() method?" You can just use the TestCase constructor.
I've heard Bruce Eckel point out that there is one subtle difference between creating your fixture in setUp() versus creating it in the TestCase constructor. JUnit creates all the TestCase instances up front, and then for each instance, calls setup(), the test method, and tearDown(). In other words, the subtle difference is that constructors are all invoked in batch up front, whereas the setUp() method is called right before each test method. But this seems to be not that useful a difference in practice.
2. Defer setting up fixtures until after all test cases are instantiated
ETutorial's Java Extreme Programming - 4.6 Set Up and Tear Down
http://etutorials.org/Programming/Java+extreme+programming/Chapter+4.+JUnit/4.6+Set+Up+and+Tear+Down/
You may be wondering why you should write a setUp( ) method instead of simply initializing fields in a test case's constructor. After all, since a new instance of the test case is created for each of its test methods, the constructor is always called before setUp( ). In a vast majority of cases, you can use the constructor instead of setUp( ) without any side effects.
In cases where your test case is part of a deeper inheritance hierarchy, you may wish to postpone object initialization until instances of derived [test] classes are fully constructed. This is a good technical reason why you might want to use setUp( ) instead of a constructor for initialization. Using setUp( ) and tearDown( ) is also good for documentation purposes, simply because it may make the code easier to read.
3. Better diagnostics in case of setup failure
JUnit best practices (JavaWorld)
http://www.javaworld.com/jw-12-2000/jw-1221-junit.html
Setting up a test case in the constructor is not a good idea. ...
Imagine [in code where setup is done in the test case constructor] 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. ...
This stack trace [of an exception thrown in setup code in the test case constructor] proves rather uninformative; it only indicates that the test case could not be instantiated.
Instead of setting up the data in the constructor, perform test setup by overriding setUp(). Any exception thrown within setUp() is reported correctly. ...
This stack trace [of an exception thrown in setUp() method instead of the test case constructor] 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.