I have a JUnit test case in an Android project that contains code that looks like this:
private static final URI TEST_RESOURCE_URL = TasksService.TASKLIST_RESOURCELIST_URL.resolve("task/test.task");
public void setUp () {
Log.i("Test", "TEST_RESOURCE_URL=" + TEST_RESOURCE_URL);
}
This test class has multiple test methods, some of which refer to (but do not attempt to modify) the value of this constant. However, when I run these tests (Android 2.2.2), all of these tests but the first one fails, and logcat shows me this:
03-03 18:56:41.791: I/Test(12008): TEST_RESOURCE_URL=http://apate.meridiandigital.net/tasks/task/test.task
03-03 18:56:42.101: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.131: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.151: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.281: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.311: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.341: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.361: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.391: I/Test(12008): TEST_RESOURCE_URL=null
03-03 18:56:42.391: I/Test(12008): TEST_RESOURCE_URL=null
How does a static final field change value like this? How do I prevent this from happening? Are there other situations where it might happen?
--- EDIT 1
I have now trimmed the code down to a smaller example that can be included in its entirety. See below:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class StaticFinalTest extends ServiceTestCase<MyService> {
public StaticFinalTest() {
super(MyService.class);
}
public static final Object CONST2 = new Object();
public void testA ()
{
assertNotNull (CONST2);
}
public void testB ()
{
assertNotNull (CONST2);
}
}
When this test runs, testA passes but testB fails. If testA is commented out, testB passes.
It seems to be important that it is a ServiceTestCase. A standard JUnit TestCase does not cause the problem. If 'CONST2' is a String, both tests pass as expected. Any other reference type seems to reproduce the problem.
It appears that AndroidTestCase
uses reflection to set all non-primitive fields to null
after each test in scrubClass
. It doesn't check to see if the fields are static or final, so this seems to be the source of the problem.
To solve it, change the field to non-final and set it inside setUp
. Also, make sure you call super.setUp()
as the first line of your setUp
to make sure the test case is properly initialized.
Is it possible that the garbage collector gets rid of it because it cannot know you're still accessing the object using JUnit?
Maybe you should create a method which sets the value initially. Don't forget to annotate it with @Begin
in order to assure the correct initialization of this variable.
Anyways in a test case, you shouldn't be assuming that previous operations succeeded. The environment you need in a JUnit task should be built up from zero each time.
regards
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With