0

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();
    }
Prajwal Waingankar
  • 2,534
  • 2
  • 13
  • 20

2 Answers2

0

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

0

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.

Prajwal Waingankar
  • 2,534
  • 2
  • 13
  • 20