19

I am new to Android Studio. I am using Android Studio 1.2 preview 2, gradle 2.2.1 and gradle plugin 1.1.0.

I cannot get around this error, when trying to run my unit tests:

java.lang.RuntimeException: Method getInstrumentation in android.test.InstrumentationTestCase not mocked

This is my test class:

public class AppPreferencesTest extends InstrumentationTestCase {

AppPreferences preferences;

@Before
public void setUp() throws Exception {
    preferences = new AppPreferences(getInstrumentation().getTargetContext());
}

...

In my build.gradle:

testCompile 'junit:junit:4.12'

I tried adding this

testOptions { 
    unitTests.returnDefaultValues = true
}

because that was mentioned in the steps that I followed at http://tools.android.com/tech-docs/unit-testing-support but it does not fix it.

I also tried creating a MockContext:

preferences = new AppPreferences(new MockContext());

but the constructor of AppPreferences than gives an error

public AppPreferences(Context context) {
    preferences = PreferenceManager.getDefaultSharedPreferences(
            context);
}

...

RuntimeException: Method getDefaultSharedPreferences in android.preference.PreferenceManager not mocked.
Frank
  • 12,010
  • 8
  • 61
  • 78

2 Answers2

15

I see you have updated your question.

Please take a look at the source of this SharedPreferencesMockContext.java: https://github.com/applicake/Beandroid/blob/master/Beanstalk%20Android%20ClientTest/src/com/applicake/beanstalkclient/test/SharedPreferencesMockContext.java.

Here is the test: https://github.com/applicake/Beandroid/blob/master/Beanstalk%20Android%20ClientTest/src/com/applicake/beanstalkclient/test/NotificationsTests.java

Here is a snippet show how they created their Mock:

  @Override
  protected void setUp() throws Exception {

    final SharedPreferencesMockContext mockContext = new SharedPreferencesMockContext(getContext());
    MockApplication mockApplication = new MockApplication(){
      @Override
      public Context getApplicationContext() {
        Log.d("tests", "Im here");
        return mockContext;
      }
    };


    context = mockContext;
    setApplication(mockApplication);
    prefs = PreferenceManager.getDefaultSharedPreferences(context);
    prefs.edit().clear().commit();

    super.setUp();
  }

I ran into this error last night. Try using "MockContext".

public class AppPreferencesTest extends InstrumentationTestCase {

AppPreferences preferences;
Context context;

@Before
public void setUp() throws Exception {
    context = new MockContext();
    preferences = new AppPreferences(context);
}

Please see other examples here: https://stackoverflow.com/a/29063736/950427

Community
  • 1
  • 1
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
  • Thanx, I already tried that before, but it will give another error inside the constructor of AppPreferences, I added this below my question. – Frank Mar 17 '15 at 14:04
  • But that's a ServiceTestCase, which is a AndroidTestCase, which will need an emulator? And it must be a ServiceTestCase or something like it, because it uses getContext() at the start of your snippet (to which the SharedPreferencesMockContext just forwards). – Frank Mar 17 '15 at 14:30
  • No, obviously you did not even try them. Copy them into your `src/main/test` folder and try out the examples. – Jared Burrows Mar 17 '15 at 14:31
  • 1
    You edited your comment before I could read the edit. You should just try mocking out `PreferenceManager.getDefaultSharedPreferences` yourself with `MockItTo`. – Jared Burrows Mar 17 '15 at 14:33
7

I couldn't get Instrumentation tests to work, using Android Studio, I guess they're still finalising the implementation. And since it needs to run on the emulator, there are faster options: regular unit tests.

Thanks to Jared's tips, I switched to Robolectric, which is easy to use on Android Studio.

androidTestCompile 'junit:junit:4.12'
androidTestCompile "org.robolectric:robolectric:3.0"

and

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.RobolectricTestRunner;
import static junit.framework.TestCase.assertEquals;

@RunWith(RobolectricTestRunner.class)
public class AppPreferencesTest {

    AppPreferences preferences;

    @Before
    public void setUp() throws Exception {
        preferences = new AppPreferences(RuntimeEnvironment.application.getApplicationContext());
    }

    @Test
    public void testIsNotificationsEnabled_Default() throws Exception {
        assertEquals(true, preferences.isNotificationsEnabled());
    }

    ...

The info here seems to be correct at this time: http://nenick-android.blogspot.nl/2015/02/android-studio-110-beta-4-and.html But will probably deprecate again in the near future, as all the info I found on this subject using google deprecated already.

Frank
  • 12,010
  • 8
  • 61
  • 78