我试图使用Mockito对Presenter类进行单元测试,但我总是以失败告终:
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()
未通过测试并显示错误。欢迎任何反馈/答复。希望有人帮助我。谢谢!
答案 0 :(得分:2)
我将首先回答您在此处提出的确切问题,但请记住,您还有一个更大的问题隐藏在编译错误的背后,稍后我将为您提供答案。 (请记住,我对Android没有真正的经验,因此确切的类名和用例可能无效,但是您的问题更多是在了解测试框架的功能而不是面向语法的情况下。)
第一个问题是您试图创建String类的模拟类型,这是最终的。正如您在Mockito的错误中看到的那样:
Mockito无法模拟/监视以下内容:
-期末课程
从本质上讲,没有真正的理由来创建String的模拟,因为您没有测试String功能。您可以只使用一个常数。
如果这是您要解决的问题,只需从@Mock
和noteColor
变量中删除textColor
批注,并使用一些恒定值对其进行初始化。
测试用例中还有另一个主要问题,那就是您试图在第二个测试的范围内使用在第一个测试中创建的EditorPresenter
。
问题是测试框架在单独的状态下运行不同的测试(正确地如此)。因此,当您在EditorPresenter
方法内创建createEditorPresenter_newNote
实例时,在showNewNote
测试方法中您将看不到该实例,因为它是一个不同的进程(不是另一个CPU进程) -只是一个简单的日常用语过程。
这就是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));
}
}