Solution 1 :
I am not sure about this. But you missed one Line of code to inject the Mock Annotation Variables may be due to that Exception is Occuring.
Code you need to include in @Before Method:
MockitoAnnotations.initMocks(this);
May be this will help you.
Reference: https://gist.github.com/marcouberti/500621c4646f5fdb8d69721d5186cac3
Solution 2 :
CalculateTimeAgo_Unit_Test.class
package io.intelehealth.client;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import com.parse.Parse;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import app.intelehealth.client.activities.homeActivity.HomeActivity;
import app.intelehealth.client.app.IntelehealthApplication;
import app.intelehealth.client.utilities.SessionManager;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;
/**
* Created by Prajwal Waingankar
* on 13-Jul-20.
* Github: prajwalmw
*/
@RunWith(MockitoJUnitRunner.class)
public class CalculateTimeAgo_UnitTest {
private HomeActivity homeActivity;
private SessionManager sessionManager;
private SharedPreferences sharedPreferences;
private Context context;
private SharedPreferences.Editor editor;
private SimpleDateFormat simpleDateFormat;
private ParsePosition parsePosition;
private Locale locale;
CalculateTimeAgo_UnitTest cal;
private int PRIVATE_MODE = 0;
private static final String PREF_NAME = "Intelehealth";
@Before
public void Setup()
{
context = mock(Context.class);
simpleDateFormat = mock(SimpleDateFormat.class);
parsePosition = mock(ParsePosition.class);
sharedPreferences = mock(SharedPreferences.class);
editor = mock(SharedPreferences.Editor.class);
when(context.getSharedPreferences(PREF_NAME, PRIVATE_MODE)).thenReturn(sharedPreferences);
when(sharedPreferences.edit()).thenReturn(editor);
sessionManager = new SessionManager(context);
homeActivity = new HomeActivity(); //It is a java class so no mocking of this class.
}
@Test
public void test_calculateTimeAgo()
{
// when(simpleDateFormat.parse(anyString(), any(ParsePosition.class)).setTime()).thenReturn();
// when(simpleDateFormat.parse(anyString(), any(ParsePosition.class)).getTime()).thenReturn(4544544L);
when(sessionManager.getLastSyncDateTime()).thenReturn("13-07-2020 20:22");
String result_time = homeActivity.CalculateAgoTime(sessionManager);
assertFalse(result_time.isEmpty());
}
}
My Issue with the SharedPreferences have been solved. I thought of using the
mock(Android_Dependency.class) format instead of the annotations @mock based flow.
Also, in the setup(),
I created the mocks in the format:
-
context
-
sharedpreference
-
editor
-
context.getsharedpreferences
-
sharedpreferences.edit()
-
sessionmanager instance creation
-
homeactivity instance creation.
I realized my mistakes when I debugged
the unit test and followed through each code line by line to find the Null Exception.
I noticed the null exception was at:
context.getSharedPrefernces()
Then, I realized that the unit test goes in the flow in the way the code is written. Creating the mocks line-by-line in the way they are written in the unit test class code.
Make sure to create mocks based on their Heirarchy of exection.
Problem :
Junit test class for Calculation the Time:
{
private HomeActivity homeActivity;
private SessionManager sessionManager;
private String result_time;
@Mock
Context context;
@Mock
SharedPreferences.Editor editor;
@Mock
SharedPreferences sharedPreferences;
@Before
public void Setup()
{
homeActivity = new HomeActivity();
sessionManager = new SessionManager(context);
when(context.getSharedPreferences(anyString(), anyInt()))
.thenReturn(sharedPreferences);
when(sharedPreferences.edit()).thenReturn(editor);
when(editor.putString(anyString(), anyString())).thenReturn(editor);
}
@Test
public void test_calculateTimeAgo()
{
when(sessionManager.getLastSyncDateTime()).thenReturn("13-07-2020 20:22");
result_time = homeActivity.CalculateAgoTime();
assertFalse(result_time.isEmpty());
}
}
Java Code Function:
public String CalculateAgoTime() {
String finalTime = "";
String syncTime = sessionManager.getLastSyncDateTime();
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm", Locale.getDefault());
ParsePosition pos = new ParsePosition(0);
long then = formatter.parse(syncTime, pos).getTime();
long now = new Date().getTime();
long seconds = (now - then) / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
String time = "";
long num = 0;
if (days > 0) {
num = days;
time = days + " " + context.getString(R.string.day);
} else if (hours > 0) {
num = hours;
time = hours + " " + context.getString(R.string.hour);
} else if (minutes >= 0) {
num = minutes;
time = minutes + " " + context.getString(R.string.minute);
}
// <For Seconds>
// else {
// num = seconds;
// time = seconds + " second";
// }
if (num > 1) {
time += context.getString(R.string.s);
}
finalTime = time + " " + context.getString(R.string.ago);
sessionManager.setLastTimeAgo(finalTime);
return finalTime;
}
I have used SessionManager class for maintaing all the SharedPref values.
Constructor:
public SessionManager(Context context) {
this._context = context;
pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
editor = pref.edit();
}
editor = pref.edit();
This line gives NullPointerException when I run my UnitTest class.
Getter & Setter for SharedPef:
public String getLastSyncDateTime() {
return pref.getString(LAST_SYNC_SUCCESS_DATE_TIME, "- - - -");
} //getting the sync value and time and saving in the sharedpref
public void setLastSyncDateTime(String lastPulledDateTime) {
editor.putString(LAST_SYNC_SUCCESS_DATE_TIME, lastPulledDateTime);
editor.commit();
}
Comments
Comment posted by Adam Neuwirth
Did you double check that PREF_NAME is a string and PRIVATE_MODE is an int?
Comment posted by Prajwal Waingankar
Yes it is…private mode is 0 value.
Comment posted by stackoverflow.com/questions/5686194/…
Check this Reference also
Comment posted by stackoverflow.com/questions/5686194/…
Check this reference also
Comment posted by Deepak Sachdeva
@PrajwalW please add getLastSyncDateTime() in sessionManager, just wanted to test same code at my side.
Comment posted by Prajwal Waingankar
Hi I updated my code like this: MockitoAnnotations.initMocks(this); in the setup() but same issue still bro.