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?
This (old) JUnit best practices article puts it like this:
The reason you need this is that for many tests you often need to initialize state before each test so that the tests can all make assumptions about the start state they're running in.
Suppose your test class wraps, say database access. After each test you'd want to remove whatever changes your tests have made to the db - if you didn't do that, each test runs against a slightly modified database. Additionally, any given test may see a different set of changes if some subset of the previous tests have failed. For example, suppose test1 does an insert, test2 checks that you're accurately reading the table size. Day 1, test1 fails, and 0 is correct. Day 2, test1 succeeds, and 1 is correct?
BTW, junit also supports
@BeforeClass
if you want to do a global setup, and setup and teardowns are optional.I think some reason should like the following:
At work we've discovered something rather interesting which answers your question. When you run a test suite, especially a large set of tests (200+) JUnit starts to use a LOT of memory, this is because ALL the tests are instanced before any actual test method is run.
We ran into a "memory leak" because of this because we used Spring to wire in some JPA EntiryManager objects for our database tests, this became A LOT of objects and a lot of memory and about half way through the tests we were getting OutOfMemory exceptions.
IMHO, best practise is to use setUp and tearDown to inject your dependencies and null out any and all class references, this will make your tests run faster and save you a lot of head ache!
Hope you learn from our mistakes :)
A custom runner such as
SpringJUnit4ClassRunner
may need to run some codes between the constructor and@Before
method. In this case, the runner may inject some dependency which the@Before
methods needs. But dependency injection can only be run after the object is constructed.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
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/
3. Better diagnostics in case of setup failure
JUnit best practices (JavaWorld)
http://www.javaworld.com/jw-12-2000/jw-1221-junit.html