Sharedpreference.edit () дает исключение NullPointerException в JUnit Testing + Mockito - PullRequest
0 голосов
/ 13 июля 2020

Тестовый класс Junit для расчета времени:

{
    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 Код Функция:

   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;
    }

Я использовал класс SessionManager для поддержания всех значений SharedPref.

Конструктор:

 public SessionManager(Context context) {
        this._context = context;
        pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
        editor = pref.edit();
    }

editor = pref.edit ();

Эта строка дает исключение NullPointerException, когда я запускаю свой класс UnitTest.

Получатель и сеттер для 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();
    }

Ответы [ 2 ]

0 голосов
/ 17 июля 2020

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());
    }
}

Моя проблема с SharedPreferences решена. Я подумал об использовании формата mock (Android_Dependency.class) вместо потока аннотаций на основе @mock.

Кроме того, в setup () я создал макеты в формате:

  • контекст

  • общие предпочтения

  • редактор

  • context.getsharedpreferences

  • sharedpreferences.edit ()

  • создание экземпляра sessionmanager

  • создание экземпляра homeactivity.

Я осознал свои ошибки, когда я debugged выполнял модульный тест и просматривал каждый код строка за строкой, чтобы найти нулевое исключение.

Я заметил, что нулевое исключение было по адресу:

context.getSharedPrefernces ()

Затем я понял, что модульный тест выполняется в потоке так, как написан код. Построчное создание макетов так, как они написаны в коде класса модульного теста.

Убедитесь, что вы создали макеты на основе их иерархии выполнения.

0 голосов
/ 15 июля 2020

Я не уверен в этом. Но вы пропустили одну строку кода для вставки имитационных переменных аннотации, возможно, из-за того, что происходит исключение.

Код, который необходимо включить в метод @Before:

MockitoAnnotations.initMocks (this);

Может быть, это вам поможет.

Ссылка: https://gist.github.com/marcouberti/500621c4646f5fdb8d69721d5186cac3

...