[UPDATE]:
我知道NPE是什么,但我不知道为什么它会出现在这里。所以我认为这完全不是一个重复的问题,因为什么是空指针异常,我该如何解决它。但无论如何,我已经找到了答案。要在仪器测试中使用Mockito,还需要添加依赖项dexmaker和dexmaker-Mockito:
androidTestCompile "com.google.dexmaker:dexmaker:1.2"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
如果您不在MockitoJUnitRunner
下运行yout测试,还需要进行额外的初始化,如下所述:
MockitoAnnotations.initMocks(this);
另请参阅初始化模拟对象-MockIto以了解更多讨论。
我想写一个简单的测试来检查用户的数据是否显示在UI上。"活动"检索存储在onResume()中的sharedPreferences中的数据,并将其显示在UI中。以下是我的测试代码:
@RunWith(AndroidJUnit4.class)
public class EditProfileActivityTest {
@Mock
private UserPreference userPreference;
private String FAKE_NAME = "Test";
@Rule
public ActivityTestRule<EditProfileActivity> activityTestRule = new ActivityTestRule(EditProfileActivity.class,true,false);
@Before
public void setUp(){
//Set fake SharedPreferences
when(userPreference.getName()).thenReturn(FAKE_NAME);
//Start Activity
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
}
@Test
public void showUserData() throws Exception{
onView(withId(R.id.name_tv)).check(matches(withText(FAKE_NAME)));
}
}
其中UserPreference是一个自定义类,它简单地封装了SharedPreference类,并包含许多getter和setter。这是它的构造函数
public UserPreference(Context context) {
this.context = context;
sharedPreferences = this.context.getSharedPreferences("Pref", Context.MODE_PRIVATE);
prefEditor = sharedPreferences.edit();
}
和它的一个吸气剂
public String getName() {
return sharedPreferences.getString(context.getString(R.string.pref_name), "Guest");
}
但当我运行测试时,它在这行上一直显示NullPointerExceptions
when(userPreference.getName()).thenReturn(FAKE_NAME);
我已经搜索了相关的主题,但我仍然不明白为什么。我认为mock的概念是重新定义一个方法的行为,无论实际实现是什么。我是测试的新手,所以如果这是一个愚蠢的问题,我很抱歉。
顺便说一下,测试使用以下代码完美运行
@RunWith(AndroidJUnit4.class)
public class EditProfileActivityTest {
private UserPreference userPreference;
private String FAKE_NAME = "Test";
@Rule
public ActivityTestRule<EditProfileActivity> activityTestRule = new ActivityTestRule(EditProfileActivity.class,true,false);
@Before
public void setUp(){
//Start Activity
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
}
@Test
public void showUserData() throws Exception{
onView(withId(R.id.name_tv)).check(matches(withText(FAKE_NAME)));
}
}
但它检索的偏好数据来自"真实"设备。在这种情况下,我无法断言将显示什么,因此我无法判断测试是否通过。这就是为什么我想嘲笑这种偏好,让它变得可预测。
您必须在@Before
中初始化mock,如下所示:
public void setUp() {
MockitoAnnotations.initMocks(this);
// ...
}
您的userPreference对象为null,但您正在尝试对其调用一个方法。如果您发布所有代码,会更容易。
Mock对象的想法是正确的,但你没有使用Mock对象,你在一个真实的对象上调用when(),但它还没有创建,因此是NPE。