I am trying to run an Instrumentation test (androidTest) using Mockito in Android with Java.
The object under test is a simple fragment with and edittext in the layout. The edittext is loaded from a shared preference value. This is the relevant code:
public class KMCountFragment extends Fragment {
static final String SHARED_PREF_FILE = "cartrip_sharedpref";
static final String PREF_KEY_START_KM = "pref_start_km";
private SharedPreferences sharedPreferences;
private int startKMCount;
private int endKMCount;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPreferences = getContext().getSharedPreferences(SHARED_PREF_FILE, MODE_PRIVATE);
startKMCount = sharedPreferences.getInt(PREF_KEY_START_KM, 0);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
...
binding.startKMCount.setText(String.valueOf(startKMCount));
}
This is the test:
@MediumTest
@RunWith(MockitoJUnitRunner.class)
public class KMCountFragmentIT {
@Mock
Context context;
@Mock
SharedPreferences sharedPrefs;
@Before
public void setUp() {
sharedPrefs = mock(SharedPreferences.class);
context = mock(Context.class);
when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
}
@Test
public void testFragmentCountersInitStata() {
when(sharedPrefs.getInt(anyString(), anyInt())).thenReturn(20);
FragmentScenario<KMCountFragment> scenario = FragmentScenario.launchInContainer(KMCountFragment.class);
scenario.moveToState(Lifecycle.State.RESUMED);
onView(withId(R.id.startKMCount)).check(matches(withText("20")));
}
}
These are my dependencies in build.gradle:
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
implementation files('libs/activation.jar')
implementation files('libs/additionnal.jar')
implementation files('libs/mail.jar')
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.security:security-crypto:1.0.0'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:4.3.1'
testImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "org.mockito:mockito-android:4.3.1"
androidTestImplementation "androidx.test:core:1.4.0"
debugImplementation "androidx.fragment:fragment-testing:1.4.1"
}
The test keeps failing because the actual value in my app prefs is 999 and the test expects 20. The real context from the app is used and not the mocked one. I tried to mock the whole context also but same result:
androidx.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'an instance of android.widget.TextView and view.getText() with or without transformation to match: is "20"' doesn't match the selected view.
Expected: an instance of android.widget.TextView and view.getText() with or without transformation to match: is "20"
Got: view.getText() was "999" transformed text was "999"
It seems like the mocking from Mockito is not working. Maybe I'm missing something stupid.. but I can't figure it out!