Reputation: 417
I am trying to do some unit tests, on fragments and activities that use SharedPrefrences
, amongst other Android related classes. However, I seem to always get a ClassNotFound
Exception when I try to mock these like the below:
ClassNotFoundException: android.content.Context
Here is an example:
My 'TimerFragment' contains a 'MyNotificationManager' class.
@RunWith(MockitoJUnitRunner.class)
public class TimerFragmentUnitTest {
@Mock
TimerFragmentView view;
@Mock
MyNotificationManger notificationManger;
private TimerFragmentPresenter presenter;
@Before
public void setUp(){
presenter = new TimerFragmentPresenter(notificationManger);
presenter.bindView(view);
}
@Test
public void shouldSendNotification() throws Exception{
//Given
doNothing().when(view).setStopEnabled(false);
doNothing().when(view).setStopEnabled(true);
//When
presenter.setMinutesAndSeconds(2000);
TimeUnit.MILLISECONDS.sleep(3000);
//Then
verify(notificationManger,times(1)).sendTimerFinishNotification();
}
}
In this example, I am getting a ClassNotFoundException: android.content.Context
error, because MyNotificationManager
has a Context
object in it.
Any advice would be appreciated.
Thanks.
Here is an implementation of the MyNotificationTimer
public class MyNotificationManger {
private static final String EXTRA_NOTIFICATION_TIMER = "notification_timer";
private static final int TIMER_NOTIFICATION_ID = 1;
private final Context _context;
public MyNotificationManger(Context context) {
_context = context;
}
public void sendTimerFinishNotification() {
int icon = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ? R.mipmap.ic_launcher : R.drawable.methodegg;
Notification.Builder builder =
new Notification.Builder(_context)
.setSmallIcon(icon)
.setContentTitle(_context.getString(R.string.timer))
.setContentText(_context.getString(R.string.ready))
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
.setAutoCancel(true);
Intent resultIntent = new Intent(_context, NavigationActivity.class);
resultIntent.putExtra(EXTRA_NOTIFICATION_TIMER, true);
PendingIntent resultPendingIntent = PendingIntent.getActivity(
_context,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
NotificationManager notificationManager = (NotificationManager) _context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(TIMER_NOTIFICATION_ID, builder.getNotification());
}
}
Upvotes: 0
Views: 809
Reputation: 417
Managed to find an answer, although Android documentation seems to believe this solution should be used only as a 'last resort'. I put
android {
testOptions {
unitTests.returnDefaultValues = true
}
}
in the top level build.gradle
.
According to documentation, this should be used if 'If you run a test that calls an API from the Android SDK that you do not mock'
, which I find bizare, as i'm not getting a 'Method ... not mocked'
error, I am getting a 'ClassNotFoundException'
Upvotes: 2