Issue
When i run the below code, both test cases come true:
import static junit.framework.Assert.assertEquals;
import org.junit.Test;
public class MyTest{
private int count;
@Before
public void before(){
count=1;
}
@Test
public void test1(){
count++;
assertEquals(2, count);
}
@Test
public void test2(){
count++;
assertEquals(2, count);
}
}
EXPECTED BEHAVIOUR
- test1 - success
- test2 - fail(as expected that count will become 3)
ACTUAL BEHAVIOUR
- test1 - success
- test2 - success
Why junit is reinitializing class/variable
with each test method invocation.
It is a bug in junit or is provided intentionally.
Solution
New Instance of MyTest
for each test method
For each test method a new instance of MyTest
will be created this is the behavior of Junit.
So in your case for both methods the variable count
will have value 1
, and thus the value of count++
will be 2
for both the test methods and hence the test cases pass.
public class MyTest{
public MyTest(){
// called n times
System.out.println("Constructor called for MyTest");
}
@Before //called n times
public void setUp(){
System.out.println("Before called for MyTest");
}
//n test methods
}
If you execute the code above with 2 test methods:
Output will be:
Constructor called for MyTest
Before called for MyTest
//test execution
Constructor called for MyTest
Before called for MyTest
Edit:
Isolation from the F.I.R.S.T principle of testing
Test frameworks help you in doing the right thing, a very important property of unit tests is isolation.
By creating a new instance every test method, the dirty SUT is thrown away. So that we have a fresh state for every test.
Read about F.I.R.S.T principle of testing.
Answered By - Narendra Pathai
Answer Checked By - David Goodson (JavaFixing Volunteer)