28

I have a problem executing android unit tests against android applications that utilize the recently released Fragment support API. When the test is run against a FragmentActivity the following error shows up in the log and the class fails to load. When run against an identical class, but one derived from Activity the test works fine. Both classes work correctly as apps! Meaning that when simply invoked they both display their layout and function correctly. The support jar is part of the build path and included in the project.

The problem I have is that the only way to utilize fragments (and support pre3.0 android) is to utilize FragmentActivity, but if that excludes automated testing then what good is this library.

4-05 18:00:11.276: WARN/dalvikvm(1095): Class resolved by unexpected DEX: Lcom/example/android/app/FragmentLayoutSupport;(0x406351a0):0x12e5c8 ref [Landroid/support/v4/app/FragmentActivity;] Landroid/support/v4/app/FragmentActivity;(0x406351a0):0x12e440
04-05 18:00:11.276: WARN/dalvikvm(1095): (Lcom/example/android/app/FragmentLayoutSupport; had used a different Landroid/support/v4/app/FragmentActivity; during pre-verification)
04-05 18:00:11.286: WARN/dalvikvm(1095): Unable to resolve superclass of Lcom/example/android/app/FragmentLayoutSupport; (49)
04-05 18:00:11.286: WARN/dalvikvm(1095): Link of class 'Lcom/example/android/app/FragmentLayoutSupport;' failed
04-05 18:00:11.286: ERROR/dalvikvm(1095): Could not find class 'com.example.android.app.FragmentLayoutSupport', referenced from method com.example.android.app.test.FrameLayoutTest.<init>
04-05 18:00:11.286: WARN/dalvikvm(1095): VFY: unable to resolve const-class 131 (Lcom/example/android/app/FragmentLayoutSupport;) in Lcom/example/android/app/test/FrameLayoutTest;

Here is the code I constructed to demonstrate the issue. The test case simply tries to instantiate the class under test:

FrameLayoutTest.java    
public class FrameLayoutTest extends
            ActivityInstrumentationTestCase2<FragmentLayoutSupport> {
        public FrameLayoutTest() {
            super(FragmentLayoutSupport.class);
        }

    public void testActivityTestCaseSetUpProperly() {
        assertNotNull("activity should be launched successfully", getActivity());
    }
}

The two classes I have created are as follows and fragment_layout is an empty LinearLayout:

FrameLayout.java
public class FragmentLayout extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.fragment_layout);
    }
}

And

FragmentLayoutSupport.java
public class FragmentLayoutSupport extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.fragment_layout);
    }
}
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
securelpb
  • 511
  • 1
  • 5
  • 7

3 Answers3

50

I spent half the night on this, and finally found a solution. The key line is:

04-05 18:00:11.276, (Lcom/example/android/app/FragmentLayoutSupport; had used a different Landroid/support/v4/app/FragmentActivity; during pre-verification). 

The problem is that the android-support-v4.jar which you are using in your test project is different from that one in your application project. Remove all of the references to android-support-v4.jar from your test project. Then go to your application project Properties->Java Build Path->Order and Export and check android-support-v4.jar to export it. Now both projects will be using the same library, and dalvik won't complain.

Alex Bonel
  • 1,344
  • 1
  • 9
  • 22
Alec B. Plumb
  • 2,490
  • 25
  • 25
  • 5
    That was exactly it. I saw that line in the debug log, but it threw me off. I thought it was saying I had used different versions of android-support-v4.jar, which I hadn't. I guess what is going on is that the build of each project with it's own linking of that jar file resulted in two uniquely encoded dex files. Very tricky and nice to have solved. I was almost ready to abandon fragments as they were, for all practical purposes, untestable if you used the support lib. – securelpb Apr 15 '11 at 05:38
  • 1
    You're a life-saver - this had been stumping me for a good three hours. – tomato Oct 28 '11 at 17:52
  • Your name should be "Life-saver" – Traveling Salesman Nov 25 '13 at 21:20
4

The IntelliJ answer by Rupert didn't get me all the way there. I solved this by exporting the jar like the Eclipse answer suggested.

File > Project Structure > Modules > [select your main app] > dependencies tab > click export check box next to the support jar

IntelliJ Project Structure

colabug
  • 2,602
  • 2
  • 22
  • 28
3

For any IntelliJ users who run into this problem the equivalent fix is to set the scope of your dependency to 'Provided' as follows:

File > Project Structure > Modules > [select your test app] > dependencies tab > select 'Provided' in scope drop down.

Rupert Bates
  • 3,041
  • 27
  • 20
  • After migration to IntelliJ 11.1 my tests stopped working. Your hint helped, thanks. – jki Apr 04 '12 at 19:32
  • I've tried all the suggestions on this page, including the dependency one......with no luck. Activity test fails instantiating the activity under test with "NoSuchMethod".... :-( – Andrew Mackenzie Oct 14 '13 at 00:03