为什么它一直在模拟对象上抛出NPE



[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。

相关内容

  • 没有找到相关文章

最新更新