Тест Мокито в схеме MVP - PullRequest
       31

Тест Мокито в схеме MVP

0 голосов
/ 16 декабря 2018

Я пытаюсь провести модульное тестирование своего класса Presenter с использованием Mockito, и я всегда заканчиваю тем, что проваливаю тест:

org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class java.lang.String
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types

Вот как выглядит мой класс Presenter:

public class EditorPresenter implements EditorContract.Presenter {

    private DataSource dataSourceImpl;
    private EditorContract.View mView;
    private SharedPreferences prefs;

    EditorPresenter(SharedPreferences prefs,
                    DataSourceImpl dataSourceImpl,
                    EditorContract.View mView) {
        this.dataSourceImpl = dataSourceImpl;
        this.mView = mView;
        this.prefs = prefs;

        mView.setPresenter(this);
    }

    @Override
    public void showNewNote() {
        String noteColor = prefs.getString("default_note_color", "#ef5350");
        String textColor = prefs.getString("default_text_color", "#000000");
        mView.noteColor(Color.parseColor(noteColor));
        mView.textColor(Color.parseColor(textColor));
     }
}

И это то, что я сделал до сих пор в классе EditorPresenterTest:

public class EditorPresenterTest {
    @Mock
    private EditorContract.View mView;
    @Mock
    private DataSourceImpl mDataSourceImpl;
    @Mock
    private SharedPreferences sharedPrefs;
    @Mock
    private String noteColor;
    @Mock
    private String textColor;

    @Before
    public void setUpEditorPresenter() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void createEditorPresenter_newNote() {
        EditorPresenter editorPresenter = new EditorPresenter(
                sharedPrefs,
                mDataSourceImpl,
                mView);
         verify(mView).setPresenter(editorPresenter);
    }
    @Test
    public void showNewNote() {
        when(sharedPrefs.getString(eq("default_note_color"), eq("#ef5350"))).thenReturn(noteColor);
        when(sharedPrefs.getString(eq("default_text_color"), eq("#000000"))).thenReturn(textColor);
        verify(mView).textColor(Color.parseColor(noteColor));
        verify(mView).noteColor(Color.parseColor(textColor));
    }

(Примечание: я новичок в Mockito и тестировании) Я прошел createEditorPresenter_newNote(), но showNewNote() не прошелтест и показывает ошибку.Любые отзывы / ответы приветствуются.Надеюсь, кто-то мне поможет.Спасибо!

1 Ответ

0 голосов
/ 16 декабря 2018

Сначала я отвечу на конкретный вопрос, который вы задали здесь, но имейте в виду, что у вас есть большая проблема, которая скрывается за вашей ошибкой компиляции, на которую я предоставлю ответ сразу после этого.(имейте в виду, что у меня нет реального опыта работы с Android, поэтому точные имена классов и варианты использования могут быть неверными, но ваши проблемы больше связаны с пониманием того, что делают тестовые среды, а не с синтаксической ориентацией).

Ваша первая проблема заключается в том, что вы пытаетесь создать фиктивные типы класса String, что является окончательным.Как вы можете видеть в ошибке от Mockito:

Mockito не может издеваться / шпионить за:

- финальные классы

По сути, нет реальной причины для создания макета String, потому что вы не тестируете функциональность String.Вы можете просто использовать константу.если это то, что вы хотите исправить, просто удалите аннотации @Mock из переменных noteColor и textColor и инициализируйте их некоторыми постоянными значениями.


Подробнее о тестировании фреймворков и другихпроблемы, с которыми вы сталкиваетесь:

В вашем тестовом примере есть еще одна серьезная проблема, заключающаяся в том, что вы пытаетесь использовать EditorPresenter, созданный вами в первом тесте, в рамках второго теста.

Дело в том, что тестовые среды запускают разные тесты в разных состояниях (справедливо).Поэтому, когда вы создаете экземпляр EditorPresenter внутри метода createEditorPresenter_newNote, он не будет виден вам в методе теста showNewNote, потому что это другой процесс (не другой процесс ЦП - просто процесс впростой ежедневный термин слова).


Что вы должны делать вместо этого?

Для этого и нужен метод before: он будет вызываться перед каждымТестовые запуски, так что вы можете настроить совместную функциональность в одном месте.

то, что вы должны сделать, это больше на линии этого:

public class EditorPresenterTest {
    @Mock
    private EditorContract.View mView;
    @Mock
    private DataSourceImpl mDataSourceImpl;
    @Mock
    private SharedPreferences sharedPrefs;

    private EditorPresenter editorPresenter;

    @Before
    public void setUpEditorPresenter() {
        MockitoAnnotations.initMocks(this);
        this.editorPresenter = new EditorPresenter(
                sharedPrefs,
                mDataSourceImpl,
                mView);
    }

    @Test
    public void createEditorPresenter_newNote() {
         verify(mView).setPresenter(editorPresenter);
    }

    @Test
    public void showNewNote() {
        editorPresenter.showNewNote();
        String noteColor = "#ef5350"; // or whatever color you want
        String textColor = "#000000"; // or whatever color you want
        when(sharedPrefs.getString(eq("default_note_color"), eq("#ef5350"))).thenReturn(noteColor);
        when(sharedPrefs.getString(eq("default_text_color"), eq("#000000"))).thenReturn(textColor);
        verify(mView).textColor(Color.parseColor(noteColor));
        verify(mView).noteColor(Color.parseColor(textColor));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...