Тест Мокито в схеме MVP
Я пытаюсь провести модульное тестирование своего класса 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 ответ
Сначала я отвечу на конкретный вопрос, который вы задали здесь, но имейте в виду, что у вас есть более крупная проблема, которая скрывается за вашей ошибкой компиляции, на которую я предоставлю ответ сразу после. (имейте в виду, что у меня нет реального опыта работы с Android, поэтому точные имена классов и варианты использования могут быть неверными, но ваши проблемы больше связаны с пониманием того, что делают тестовые среды, а не с синтаксически-ориентированной).
Ваша первая проблема заключается в том, что вы пытаетесь создать фиктивные типы класса String, что является окончательным. Как вы можете видеть в ошибке от 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));
}
}